TIL 25. 콜백 함수와 클로저

isk·2022년 12월 2일
0

TIL

목록 보기
25/122
post-custom-banner

콜백 함수란

다른 코드의 인자로 넘겨주는 함수.

setInterval(cbFunc, 1000);

위의 코드가 콜백함수를 사용한 코드다.
setInterval(cbFunc, 1000) 코드는 1000밀리초마다(1초) cbFunc라는 또 다른 함수를 실행시킨다.

chFunc()는 내가 호출시키고 내가 제어하지만,
setInterval(cbFunc, 1000) 코드는, setInterval이 cbFunc()함수를 호출시키고, 제어한다.

콜백 함수를 사용하는 상황

비동기적 코드의 동기적 사용이 필요할 때.

function callback () {
	console.log("a");
}

fetch('html').than(callback);

console.log(1);
console.log(2);

// 1
// 2
// a

위 코드처럼 a, 1, 2 순서로 출력되게 하고 싶었지만, fetch는 비동기적 코드다.
이런 상황에서 콜백함수를 사용할 수 있고, 콜백함수가 아닌 promise, generator, async/await도 사용할 수 있다.
async/await가 사용하기 편하고 가독성도 좋아서 주로 사용한다.


클로저(closure)

클로저란 함수와 그 함수가 선언된 렉시컬 환경의 조합이다.

외부 함수가 return을 했기 때문에 콜 스택에서 제거되지만,
내부 함수가 참조하고 있기 때문에 렉시컬 환경에는 아직 남아있다. (가바지 컬렉터가 안가져간다.)

마치 스택에서 제거될 때의 상태를 기억하고 사라졌다가, 다시 호출하면 기억한 상태로 복귀하는 느낌.

자신이 선언될 당시의 환경을 기억하는 함수라고 보면 될 것 같다.

클로저의 핵심은 스코프를 이용해서, 변수의 접근 범위를 닫는(폐쇄)것에 있다.
함수가 호출되는 환경과 별개로, 기존에 선언되어 있던 환경(어휘적 환경)을 기준으로 변수를 조회한다.

클로저는 console.log 같은 실행만 띡 하고 사라지는 함수가 아니면서 상위 스코프(외부 식별자)를 참조해야한다.

외부 식별자를 참조하지만, 호출되어 실행만 하고 소멸된다면 클로저 x
return값이 되어, 외부 함수보다 더 오래 유지 되어도 상위 스코프(외부 식별자)를 참조하지 않는다면 클로저 x

코어 자바스크립트 저자 왈,
클로저는 let 선언을 해라.
다 쓰면 의도적으로 없애라.

  • 우리가 주로 사용하는 콜백 함수는 클로저로 구현되어 있다.

  • 정보 은닉이 필요한 상황에서 유용하게 사용될 수 있다.

function createCounter() {
  let count = 0;
  return function() {
    return ++count;
  }
}

const counter = createCounter();
console.log(counter()); // 출력: 1
console.log(counter()); // 출력: 2

클로저 내부에서 선언된 변수는 외부에서 접근할 수 없기 때문에, 클로저를 사용하여 정보를 은닉하고 접근을 제어할 수 있다.

  • 클로저를 사용하여 반복문의 문제를 해결할 수 있다.
    예를 들어, 반복문 내에서 비동기 작업을 처리하려면 클로저를 사용하여 반복문 변수의 값이 유지되도록 할 수 있다.
for (var i = 1; i <= 5; i++) {
  (function(index) {
    setTimeout(function() {
      console.log(index);
    }, 1000 * index);
  })(i);
}

  • 클로저 x (상위 스코프 참조 X)
function foo() {
  const x = 1;
  const y = 2;
  
  function bar() {
    const z = 3;
    
    console.log(z); // 상위 스코프의 식별자 참조 X, 같은 스코프의 식별자 참조
  }
  return bar;
}
const bar = foo();
bar();

  • 클로저 X (바로 소멸)
function foo() {
  const x = 1;
  
  function bar() {	// 곧바로 소멸
    debugger;
    console.log(x);
  }
  bar(); // 얘 때문에 안돼
}
foo();

  • 클로저 O
function foo() {
  const x = 1;
  const y = 2;
  
  function bar() {	// 외부 함수보다 더 오래 유지. 
    debugger;
    console.log(x);	// 상위 스코프의 식별자 참조.
  }
  return bar;
}

const bar = foo();
bar();

function makeAdder(x) {
  // 클로저
  return function(y) {
    return x + y;
  }
}

const add5 = makeAdder(5);
console.log(add5(3)); // 출력: 8

위의 코드에서 makeAdder라는 함수는 인자로 받은 x 값을 기억하고 있는 클로저 함수를 반환한다.
반환된 클로저 함수 add5x 값을 기억하고 있어, 나중에 호출될 때에도 x 값을 사용할 수 있다.
따라서 add5 함수를 호출할 때에는 5와 인자를 더하여 원하는 결과를 얻게 된다.

클로저는 함수가 생성될 때의 상태를 기억하고 있기 때문에, 함수 내에서는 해당 상태를 사용하거나 변경할 수 있다. 이를 통해 동적인 동작이 필요한 경우에 유용하게 사용될 수 있다. 클로저는 함수형 프로그래밍이나 자바스크립트의 높은 차원의 유연성과 표현력을 지원하는 중요한 개념 중 하나다.


어느정도 이해는 된 것 같은데, 설명하라고 하면 못하겠다.. 계속 공부해야겠다!

post-custom-banner

0개의 댓글