function createCounter() {
let count = 0; // 외부 함수의 지역 변수 (가방 속 물건)
// 내부 함수는 count 변수를 기억하는 클로저가 됩니다.
return function() {
count++;
console.log(count);
};
}
const counter = createCounter(); // counter 변수는 이제 클로저를 가리킵니다.
counter(); // 1
counter(); // 2
createCounter
함수는 실행이 끝났지만, 그 안의 count
변수는 counter
가 참조하는 내부 함수(클로저) 덕분에 사라지지 않고 계속 살아남아 값을 기억하고 있습니다.
이것이 바로 클로저를 통해 var
와 let
, const
의 차이var
로 선언된 변수는 호이스팅되면서 undefined
로 초기화됩니다.
따라서 선언 전에 호출해도 오류가 나지 않고 undefined
가 출력됩니다.
console.log(myVar); // undefined (오류가 나지 않음)
var myVar = 10;
let
과 const
로 선언된 변수는 호이스팅되지만 초기화되지는 않습니다.
이 때문에 선언문이 나오기 전까지 '일시적 사각지대(TDZ, Temporal Dead Zone)'에 빠져, 접근하려고 하면 참조 에러(ReferenceError)가 발생합니다.
이것이 var
보다 let
, const
의 사용이 권장되는 중요한 이유 중 하나입니다.
console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization
let myLet = 10;
div
를 클릭하면, 먼저 안쪽 div
의 클릭 이벤트 핸들러가 동작하고, 그 다음 바깥쪽 div
의 핸들러, 그리고 body
, html
, document
순서로 이벤트가 전파됩니다.
<div id="outer">
바깥쪽
<div id="inner">안쪽</div>
</div>
<li>
각각에 이벤트 리스너를 다는 대신, 그들의 부모인 <ul>
에 단 하나의 리스너만 달아두고, 이벤트가 버블링되어 올라왔을 때 실제 이벤트가 발생한 대상(event.target
)을 확인하여 처리하는 방식입니다.
이를 event.stopPropagation()
메서드를 호출하여 버블링을 중단시킬 수 있습니다.클로저는 함수가 자신의 렉시컬 스코프를 기억하여, 외부에서 호출될 때도 내부 변수에 접근할 수 있는 함수입니다. 이를 통해전역 변수의 사용을 줄이고 데이터를 은닉하여, 외부로부터의 의도치 않은 변경을 막는private변수처럼 활용할 수 있습니다. 또한, 함수가 호출될 때마다 독립적인 상태를 유지하는상태 저장 카운터나 모듈 패턴등을 구현하는 데 사용될 수 있습니다.
var
와 let
의 호이스팅 동작 차이를 설명해주세요. 🔗호이스팅은 자바스크립트 엔진이 변수와 함수의 선언을 스코프 최상단으로 옮기는 것처럼 처리하는 동작을 말합니다.var
로 선언된 변수는 호이스팅되면서undefined
로 초기화되기 때문에, 선언문 이전에 접근해도 오류 없이undefined
를 반환합니다. 반면,let
과const
는 선언만 호이스팅될 뿐 초기화되지 않아, 선언문 이전에 접근하면일시적 사각지대(TDZ)에 의해 참조 에러가 발생합니다.
var
와 let
/const
의 차이를 만듭니다.