π Chapter 5: ν΄λ‘μ
π ν΄λ‘μ μ μλ―Έ λ° μ리 μ΄ν΄β
- ν΄λ‘μ (Closure)λ μ¬λ¬ ν¨μν νλ‘κ·Έλλ° μΈμ΄μμ λ±μ₯νλ 보νΈμ μΈ νΉμ±μ΄λ€.
- ν΄λ‘μ λ₯Ό ν λ¬Έμ₯μΌλ‘ μμ½
- μμ μ λ΄ν¬νλ ν¨μμ 컨ν μ€νΈμ μ κ·Όν μ μλ ν¨μ (μλ°μ€ν¬λ¦½νΈ ν΅μ¬ κ°μ΄λ)
- ν¨μκ° νΉμ μ€μ½νμ μ κ·Όν μ μλλ‘ μλμ μΌλ‘ κ·Έ μ€μ½νμμ μ μνλ κ² (λ¬λ μλ°μ€ν¬λ¦½νΈ)
- ν¨μλ₯Ό μ μΈν λ λ§λ€μ΄μ§λ μ ν¨λ²μκ° μ¬λΌμ§ νμλ νΈμΆν μ μλ ν¨μ (μλ°μ€ν¬λ¦½νΈ λμ λΉκΈ)
- μ΄λ―Έ μλͺ μ£ΌκΈ°μ λλ μΈλΆ ν¨μμ λ³μλ₯Ό μ°Έμ‘°νλ ν¨μ (μΈμ¬μ΄λ μλ°μ€ν¬λ¦½νΈ)
- μμ λ³μκ° μλ ν¨μμ μμ λ³μλ₯Ό μ μ μλ νκ²½μ κ²°ν© (Head First Javascript Programming)
- λ‘컬 λ³μλ₯Ό μ°Έμ‘°νκ³ μλ ν¨μ λ΄μ ν¨μ (μλ°μ€ν¬λ¦½νΈ λ§μ€ν°λΆ)
- μμ μ΄ μμ±λ λμ μ€μ½νμμ μ μ μμλ λ³μλ€ μ€ μΈμ κ° μμ μ΄ μ€νλ λ μ¬μ©ν λ³μλ€λ§μ κΈ°μ΅νλ©° μ μ§μν€λ ν¨μ (ν¨μν μλ°μ€ν¬λ¦½νΈ νλ‘κ·Έλλ°)
- ν΄λ‘μ λ ν¨μμ κ·Έ ν¨μκ° μ μΈλ λΉμμ lexical environment(λ μ컬 νκ²½)μ μνΈκ΄κ³μ λ°λ₯Έ νμ (MDN)
- μ΄λ€ 컨ν μ€νΈ Aμμ μ μΈ ν λ΄λΆν¨μ Bμ μ€ν 컨ν μ€νΈκ° νμ±νλ μμ μλ Bμ outerEnvironmentReferenceκ° μ°Έμ‘°νλ λμμΈ Aμ LexicalEnvironmentμλ μ κ·Όμ΄ κ°λ₯νλ€. Aμμλ Bμμ μ μΈν λ³μμ μ κ·Όν μ μμ§λ§ Bμμλ Aμμ μ μΈν λ³μμ μ κ·Όμ΄ κ°λ₯νλ€.
- λ΄λΆν¨μμμ μΈλΆ λ³μλ₯Ό μ°Έμ‘°νμ§ μλ κ²½μ°λ ν΄λΉνμ§ μλλ€. μ¦, μ μΈλ λΉμμ LexicalEnvironmentμμ μνΈκ΄κ³μ΄λ€.
var outer = function() {
var a = 1;
var inner = function() {
console.log(++a); // 2
};
inner();
};
outer();
- μ μμμ
inner
ν¨μ λ΄λΆμμλa
λ₯Ό μ μΈνμ§ μμκΈ° λλ¬Έμ environmentRecordμμ κ°μ μ°Ύμ§ λͺ»νλ―λ‘ outerEnvironmentReferenceμ μ§μ λ μμ 컨ν μ€νΈμΈ LexicalEnvironmentμ μ κ·Όν΄μ λ€μa
λ₯Ό μ°Ύλλ€. outer
ν¨μμ μ€ν 컨ν μ€νΈκ° μ’ λ£λλ©΄ LexicalEnvironmentμ μ§μ λ μλ³μλ€(a
,inner
)μ λν μ°Έμ‘°λ₯Ό μ§μ΄λ€. κ·Έλ¬λ©΄ κ° μ£Όμμ μ μ₯λΌ μλ κ°λ€μ μμ μ μ°Έμ‘°νλ λ³μκ° νλλ μκ² λλ― λ‘ κ°λΉμ§ 컬λ ν°μ μμ§ λμμ΄ λ κ²μ΄λ€.
var outer = function() {
var a = 1;
var inner = function() {
return ++a;
};
return inner();
};
var outer2 = outer();
console.log(outer2); // 2
- μ μμ μμλ
inner
ν¨μλ₯Ό μ€νν κ²°κ³Όλ₯Ό 리ν΄νκ³ μμΌλ―λ‘ κ²°κ³Όμ μΌλ‘outer
ν¨μμ μ€ν 컨ν μ€νΈκ° μ’ λ£λ μμ μλa
λ³μλ₯Ό μ°Έμ‘°νλ λμμ΄ μμ΄μ§λ€. - μ λ μμ μμ
outer
ν¨μμ μ€ν 컨ν μ€νΈκ° μ’ λ£λκΈ° μ΄μ μinner
ν¨μμ μ€ν 컨ν μ€νΈκ° μ’ λ£λΌ μμΌλ©°, μ΄ν λ³λμinner
ν¨μλ₯Ό νΈμΆν μ μλ€λ 곡ν΅μ μ΄ μλ€. - κ·Έλ λ€λ©΄
outer
μ μ€ν 컨ν μ€νΈκ° μ’ λ£λ νμλinner
ν¨μλ₯Ό νΈμΆν μ μκ² λ§λ€λ©΄ μ΄λ¨κΉ?
var outer = function() {
var a = 1;
var inner = function() {
return ++a;
};
return inner;
};
var outer2 = outer();
console.log(outer2()); // 2
console.log(outer2()); // 3
- μ μμ μμ
inner
ν¨μ μ체λ₯Ό λ°ννλ€. κ·Έλ¬λ©΄outer
ν¨μμ μ€ν 컨ν μ€νΈκ° μ’ λ£λ λouter2
λ³μλouter
μ μ€ν κ²°κ³ΌμΈinner
ν¨μλ₯Ό μ°Έμ‘°νκ² λ κ²μ΄λ€. inner
ν¨μμ μ€ν 컨ν μ€νΈμ environmentRecordμλ μμ§ν μ λ³΄κ° μλ€. outerEnvironmentReferenceμλinner
ν¨μκ° μ μΈλ μμΉμ LexicalEnvironmentκ° μ°Έμ‘°λ³΅μ¬λλ€.inner
ν¨μλouter
ν¨μ λ΄λΆμμ μ μΈλμΌλ―λ‘,outer
ν¨μμ LexicalEnvironmentκ° λ΄κΈΈ κ²μ΄λ€.- μ΄μ μ€μ½ν 체μ΄λμ λ°λΌ
outer
μμ μ μΈν λ³μa
μ μ κ·Όν΄μ 1λ§νΌ μ¦κ°μν¨ ν κ·Έ κ°μΈ 2λ₯Ό λ°ννκ³ ,inner
ν¨μμ μ€ν 컨ν μ€νΈκ° μ’ λ£λλ€. - κ·Έλ°λ°
inner
ν¨μμ μ€ν μμ μλouter
ν¨μλ μ΄λ―Έ μ€νμ΄ μ’ λ£λ μνμΈλ°outer
ν¨μμ LexicalEnvironmentμ μ΄λ»κ² μ κ·Όνλ κ²μΌκΉ? - μ΄λ κ°λΉμ§ 컬λ ν°μ λμ λ°©μ λλ¬ΈμΈλ° κ°λΉμ§ 컬λ ν°λ μ΄λ€ κ°μ μ°Έμ‘°νλ λ³μκ° νλλΌλ μλ€λ©΄ κ·Έ κ°μ μμ§ λμμ ν¬ν¨μν€μ§ μλλ€.
outer
ν¨μλ μ€ν μ’ λ£ μμ μinner
ν¨μλ₯Ό λ°ννλ€. μΈλΆν¨μμΈouter
μ μ€νμ΄ μ’ λ£λλλΌλ λ΄λΆ ν¨μμΈinner
ν¨μλ μΈμ κ°outer2
λ₯Ό μ€νν¨μΌλ‘μ¨ νΈμΆλ κ°λ₯μ±μ΄ μ΄λ¦° κ²μ΄λ€. λλ¬Έμ κ°λΉμ§ 컬λ ν°μ μμ§ λμμμ μ μΈκ° λλ κ²μ΄λ€.- μ΄μ²λΌ ν¨μμ μ€ν 컨ν μ€νΈκ° μ’ λ£λ νμλ LexicalEnvironmentκ° κ°λΉμ§ 컬λ ν°μ μμ§ λμμμ μ μΈλλ κ²½μ°λ λ§μ§λ§ μμ μ²λΌ μ§μλ³μλ₯Ό μ°Έμ‘°νλ λ΄λΆν¨μκ° μΈλΆλ‘ μ λ¬λ κ²½μ°κ° μ μΌνλ€.
ν΄λ‘μ λ₯Ό λ€μ μ μν΄λ³΄λ©΄ ν΄λ‘μ λ μ΄λ€ ν¨μ Aμμ μ μΈν λ³μ aλ₯Ό μ°Έμ‘°νλ λ΄λΆν¨μ Bλ₯Ό μΈλΆλ‘ μ λ¬ν κ²½μ° Aμ μ€ν 컨ν μ€νΈκ° μ’ λ£λ μ΄νμλ λ³μ aκ° μ¬λΌμ§μ§ μλ νμμ΄λ€.
- νκ°μ§ μ£Όμν μ μ μΈλΆλ‘ μ λ¬μ΄ 곧
return
λ§μ μλ―Ένλ κ²μ μλλ€. μλ μ½λλreturn
μμ΄λ ν΄λ‘μ κ° λ°μνλ μν©μ΄λ€.
// setInterval/setTimeout
(function () {
var a = 0;
var intervalId = null;
var inner = function () {
if(++a >= 10) {
clearInterval(intervalId);
}
console.log(a);
};
intervalId = setInterval(inner, 1000);
})();
// eventListener
(function () {
var count = 0;
var button = document.createElement('button');
button.innerText = 'click';
button.addEventListener('click', function () {
console.log(++count, 'times clicked');
});
document.body.appendChild(button);
})();
- μ λ μν© λͺ¨λ μ§μλ³μλ₯Ό μ°Έμ‘°νλ λ΄λΆν¨μλ₯Ό μΈλΆμ μ λ¬νκΈ° λλ¬Έμ ν΄λ‘μ μ΄λ€.
π ν΄λ‘μ μ λ©λͺ¨λ¦¬ κ΄λ¦¬β
- ν΄λ‘μ λ μ΄λ€ νμμ μν΄ μλμ μΌλ‘ ν¨μμ μ§μλ³μλ₯Ό λ©λͺ¨λ¦¬λ₯Ό μλͺ¨νλλ‘ ν¨μΌλ‘μ¨ λ°μνλ€. κ·Έλ λ€λ©΄ κ·Έ νμμ±μ΄ μ¬λΌμ§ μμ μλ λλ λ©λͺ¨λ¦¬λ₯Ό μλͺ¨νμ§ μκ² ν΄μ£Όλ©΄ λλ€.
// return μ μν ν΄λ‘μ μ λ©λͺ¨λ¦¬ ν΄μ
var outer = (function () {
var a = 1;
var inner = function () {
return ++a;
};
return inner;
})();
console.log(outer());
console.log(outer());
outer = null; // outer μλ³μμ inner ν¨μ μ°Έμ‘°λ₯Ό λμ
console.log(outer()); // TypeError: outer is not a function
setInterval
μ μν ν΄λ‘μ λ©λͺ¨λ¦¬ ν΄μ
(function () {
var a = 0;
var intervalId = null;
var inner = function () {
if(++a >= 10) {
clearInterval(intervalId);
inner = null; // inner μλ³μμ ν¨μ μ°Έμ‘°λ₯Ό λμ
}
console.log(a);
};
intervalId = setInterval(inner, 1000);
})();
eventListener
μ μν ν΄λ‘μ λ©λͺ¨λ¦¬ ν΄μ
(function () {
var count = 0;
var button = document.createElement('button');
button.innerText = 'click';
var clickHandler = function () {
console.log(++count, 'times clicked');
if(count >= 10) {
button.removeEventListener('click', clickHandler);
clickHandler = null; // clickHandler μλ³μμ ν¨μ μ°Έμ‘°λ₯Ό λμ
}
};
button.addEventListener('click', clickHandler);
document.body.appendChild(button);
})();