JavaScript 값과 함수 & 콜백함수

seul_velog·2021년 12월 4일
1

JavaScript

목록 보기
9/25
post-thumbnail
post-custom-banner

1. 값으로써의 함수

📌 한 번 더 check ! )
자바스크립트 함수는 일급객체(first-class object)이다.

  • 무명의 리터럴로 표현이 가능하다.
  • 변수나 자료 구조(객체, 배열…) 데이터에 저장할 수 있다.
  • 함수의 매개변수(parameter)로 전달 할 수 있다.
  • 반환값(return value)으로 사용할 수 있다.
  • 🧐 콜백함수는 이 중에서 두번째와 세번째 특징을 활용한 내용처럼 보인다.

함수는 값이기 때문에 다른 함수의 인자로 전달 될 수 있다.

예제 1-1.

function a(func,num){
   return func(num);
}

function b(num1){
   return num1+2;
}

function c(num2){
   return num2-3;
}

console.log(a(b,5));  // 7
console.log(a(c,8));  // 5

📌 내가 이해한 대로 정리해 보자.
✍️ console.log(a(b,5)); 에서 a(b,5) 가 함수를 호출함과 동시에 function a(func, num) 에 인자로 전달되고, 마찬가지로 func(num)function b(num1) 의 인자로 전달됨과 동시에 호출되며 그 값이 리턴되는 과정을 차근차근 따라가니 이해할 수 있었다. 🙂


함수는 함수의 리턴 값으로도 사용할 수 있다.

예제 1-2.

function cal(a){
   const func = {
    'plus' : function(left, right) {return left + right},
    'minus' : function(left,right) {return left - right},
    'multiply' : function(left, right) {return left*right},
    'divide' : function(left, right) {return left/right},
    'remainder' : function(left, right) {return left%right}
  }
  return func[a];
}

console.log(cal('plus') (2,3));  // 5
console.log(cal('minus') (5,1));  // 4
console.log(cal('multiply') (3,4));  // 12
console.log(cal('divide')(10,2));  // 5
console.log(cal('remainder')(20,3))  // 2

📌 내가 이해한 대로 정리해 보자.
✍️ cal('plus')(2,3) 에서 첫번째 인수('plus') , 두번째 인수(2,3) 가 인자로써 전달이 된다. 다음으로 객체 func 안의 'plus' 키의 값인 함수에 전달할 첫번째 인자는 2, 두번째 인자는 3이다. 그 값이 실행되고 리턴된다!


함수는 값이기 때문에, 값을 저장하는 컨테이너인 배열에도 저장할 수 있다.

예제 1-3.

const process = [
  function(input) { return input + 5; },
  function(input) { return input * input; },
  function(input) { return input / 2;}
];

let input = 1;
for(let i = 0; i < process.length; i++ ) {
	input = process[i](input);
}

console.log(input);  // 18  (1+5=6, 6*6=36, 36/2=18)

📌 내가 이해한 대로 정리해 보자.
✍️ 배열에다가 함수를 저장해서 그것을 실행하는 것을 통해서 어떠한 일련의 작업을 처리하게 한다.

(1) 이 배열의 첫번째 값, 두번째 값, 세번째 값 모두 함수이다.
(2) process 라고 하는 이 배열의 길이 보다 i 값이 작은 동안 i 값을 1씩 증가시키면서 반복문을 호출한다.(i 값은 0, 1, 2 가 만들어지게 된다)
(3) i 값을 process[i] 에 넣게 되면, i 값이 0 일때는 function(input) { return input + 5; } 를 의미한다.
(4) 마찬가지로 i 값이 1일때, 2일때 각각의 함수들을 의미하게 된다.
(5) input 의 값을 인자로 전달하게 되는데, i 값이 0일때 프로세스의 첫번째 원소를 가리키게 되는 것이고, 이 첫번째 함수는 1 + 5 = 6 이며 이것을 리턴하게 되면, 그 값이 다시 9행의 input 에 저장하게 되고, 이 반복은 i 가 2가 될때까지 반복된다. 마지막으로 input 값은 18이된다.




2. 콜백함수(Callback function)란?

콜백함수는 다른 함수에 매개변수로 넘겨준 함수를 말한다. 함수를 명시적으로 호출하는 방식이 아니라 특정 이벤트가 발생했을 때 시스템에 의해 호출된다.

  • 콜백 함수는 매개변수를 통해 전달되고 전달받은 함수의 내부에서 어느 특정시점에 실행된다는 것이다.
  • 어떤 특별한 문법적 구조를 가진 것은 아니며 호출방식에 의한 구분이다.



콜백은 값으로써의 함수와 밀접하게 관련되어 있다.

예제 2-1.

const numbers = [20, 15, 9, 8, 6, 4, 3, 2, 1]
const sortF = function(a,b){
	console.log(a, b);
  if(a > b){
  return 1;
  } else if(a < b){
  return -1;
  }else{
  return 0;
  }
};
numbers.sort(sortF)
console.log(numbers);

📌 내가 이해한 대로 정리해 보자.
✍️ 배열 객체를 만들어서 numbers 라고 하는 변수에다가 담아준다. 그리고 배열객체에는 sort 라는 함수가 본래 정의되어 있으므로 우리는 배열객체.sort를 통해서 배열이 갖고 있는 명령어(sort)를 호출 할 수 있게 되는 것이다. 이러한 맥락에서 sort()는 함수라고 부르지않고 객체에 속해 있기 때문에 메소드 라고 부른다.

▼ 위와 같이 표현해도 좋지만 이러한 특성을 활용해서 아래 처럼 간단하게 작성할 수도 있다고 한다. return a - b;

const numbers = [20, 15, 9, 8, 6, 4, 3, 2, 1];
const sortF = function(a,b){
  return a - b;
  };
numbers.sort(sortF);
console.log(numbers);

간단한 예를 만들어서 콜백함수를 알아보자!

예제 2-2.

// ex1.)
function randomQuiz(ans, yes, no){
  if(ans === 'seul'){
  yes();
  }else{
  no();
  }
}

// anonymous function
const yes = function(){
console.log('hello!!');
}
// arrow function: const yes = () => console.log('hello!!');

// named function
const no = function print(){
console.log('no~');
}

randomQuiz('seul', yes, no);  // "hello!!"
randomQuiz('bye', yes, no);  // "no~"

📌 내가 이해한 대로 정리해 보자.
✍️ 함수를 선언하고 전달하려면
randomQuiz 라는 함수를 선언해서, (1)정답과 (2)정답이 맞을 때 호출하게 될 함수 (3)정답이 아닐 때 호출하게 될 함수를 전달한다. 이 함수들을 전달해서, 상황이 맞다면 이 전달된 함수를 호출하도록 전달하는 것을 콜백 함수라고한다.

즉 두가지의 콜백함수 yes, noparameter(매개변수) 로 전달 된다.

정답이 맞는 (true) 경우
: yes 라는 콜백함수를 호출한다.
만약 정답이 아니라면
: no 라는 콜백함수를 호출하게 된다.


✍️ 이 함수를 호출하려면
(1)정답을 전달할 ans, 그리고 (2)yes (3)no 라는 함수표현식(expression) 두 가지를 전달해야 한다.

나는 여기서 yes 라는 변수를 만들어서 'hello!'를 출력하는 함수를 할당하고, no 라는 변수에는 'no~'를 출력하는 함수를 할당에 놓았다.


✍️ 호출해서 결과 확인하기
▶ 마지막 1~2행을 보면, randomQuiz 를 호출할때, ans의 인수로는 각각 'seul'(정답)과 'bye'(오답)을 넣고, yesno 의 콜백함수들을 전달해 보았다. 그래서 if 문의 정답이 맞으면 yes 라는 콜백함수를 호출, elseno 라는 콜백함수를 호출하는 것을 볼 수 있다!


✍️ 함수의 이름
const yes = function() 에는 이름이 없는 anonymous function이 쓰여졌고,
const no = function print() 에는 함수 이름이 print 라고 지정이 되어있는데 이것은 named function 이라고 한다.

▶ 이렇게 함수 표현식(Function expression)에서 이름을 쓰는 경우는, 우리가 디버깅을 할때 디버깅의 stack traces 에 함수의 이름이 나오게 하기위해 쓰는 것이라고 한다. ( 식별자로써 구분하기 위함인 것 같다. 🤔 )

또는, 함수 안에서 자신 스스로 또 다른 함수를 호출할 때 쓰인다고 한다.(재귀함수) 피보나치 수열, 반복되는 평균값 등을 계산 할 때에 쓰인다. 즉 필요할 때 사용하는 것이 좋다. (함수를 무한대로 호출하게 되면 콜스택이 꽉찼다고 에러가 뜬다.)


✍️ Arrow function
위의 예제에서 arrow function 을 사용해서 함수를 간결하게 만들어보자!

// anonymous function
function randomQuiz(ans, yes, no){
  if(ans === 'seul'){
  yes();
  }else{
  no();
  }
}const yes = () => console.log('hello!!');

const no = function print(){
console.log('no~');
}

randomQuiz('seul', yes, no);  // "hello!!"
randomQuiz('bye', yes, no);  // "no~"

마찬가지로 함수가 잘 작동되는 것을 볼 수 있다 😊



대표적인 콜백 함수의 사용 예를 만들어보자! (이벤트 핸들러)

예제 2-3.

<button id='button1' onclick='button_click();'> 나는 버튼! </button>
<script>
function button_click(){
	alert('hello button :) !');
}
</script>

📌 내가 이해한 대로 정리해 보자.
✍️ HTML에서 onclick 에 콜백함수를 전달한다.
여기서 콜백 함수는 function button_click() 이며, 이 함수는 브라우저의 javascript API에서 DOM이벤트 핸들러에 전달, 즉 등록이 되고, 해당 버튼에 클릭 이벤트가 발생하면 콜백함수를 호출하게 되는 것이다.

✍️ 내가 이고잉님 강좌를 보면서 만들었던 function nightDayHandler 도 이와같은 원리로 만들었다는 것을 알 수 있게 되었다. 😀 조금 더 이 원리를 이해하고 싶어져서 찾아본 키워드는 DOMEvent, 그리고 비동기식 처리 모델(Asynchronous processing model) 인데, 다음에는 이들에 대해서도 공부해야겠다!


▼ result




reference
dream-coding coding-everybody

profile
기억보단 기록을 ✨
post-custom-banner

0개의 댓글