<star />
ν΄λ‘μ (Closure) λ³Έλ¬Έ
ν΄λ‘μ λ ν¨μμ κ·Έ ν¨μκ° μ μΈλ λ μ컬 νκ²½μ μ‘°ν©μ΄λ€. π
A closure is the combination of a function and the lexical environment within which that function was declared.
λͺ¨λ ν¨μν μΈμ΄κ° κ°μ§κ³ μλ κ°μ₯ μ€μν νΉμ±μ.
μ€μ½νμ μμ±μ νμ©ν μμ/μΈλΆ μλ³μλ₯Ό μ κ·Όν¨. (μλμ±κ³Ό μ€μ½ν μ²΄μΈ μ μ΄)
1) λ μ컬 μ€μ½ν
- μλ°μ€ν¬λ¦½νΈλ λ μ컬 μ€μ½νλ₯Ό λ°λ₯΄λ νλ‘κ·Έλλ° μΈμ΄λ€.
- μλ°μ€ν¬λ¦½νΈ μμ§μ ν¨μλ₯Ό μ΄λμ νΈμΆνλμ§κ° μλλΌ, ν¨μλ₯Ό μ΄λμ μ μνλμ§μ λ°λΌ μμ μ€μ½νλ₯Ό κ²°μ ν¨.
μ΄λ₯Ό λ μ컬 μ€μ½ν (μ μ μ€μ½ν)λΌ νλ€.
const x = 1;
function foo() {
const x = 10;
bar();
}
function bar() {
console.log(x);
}
foo(); //1
bar(); //1
- ν¨μμ μμ μ€μ½νλ ν¨μλ₯Ό μ΄λμ μ μνλλμ λ°λΌ κ²°μ λλ―λ‘, foo ν¨μμ bar ν¨μμ μμ μ€μ½νλ μ μμ΄λ€.
- ν¨μμ μμ μ€μ½νλ ν¨μλ₯Ό μ μν μμΉμ μν΄ μ μ μΌλ‘ κ²°μ λκ³ λ³νμ§ μμ.
- μ€μ½νμ μ€μ²΄λ μ€ν 컨ν μ€νΈμ λ μ컬 νκ²½μ΄λ€<<< λ μ컬 νκ²½μ μμ μ "μΈλΆ λ μ컬 νκ²½μ λν μ°Έμ‘° (Outer Lexical Environment Reference) λ₯Ό ν΅ν΄ μμ λ μ컬 νκ²½κ³Ό μ°κ²°λλ€! μ΄κ²μ΄ λ°λ‘ μ€μ½ν 체μΈμ΄λ€.
- μ¦, λ μ컬 νκ²½μ "μΈλΆ λ μ컬 νκ²½μ λν μ°Έμ‘°" μ μ μ₯ν μ°Έμ‘°κ°, μμ μ€μ½νμ λν μ°Έμ‘°λ ν¨μ μ μκ° νκ°λλ μμ μ ν¨μκ° μ μλ νκ²½(μμΉ) μ μν΄ κ²°μ λλ€. μ΄κ²μ΄ λ°λ‘ λ μ컬 μ€μ½νλ€.
2) ν¨μ κ°μ²΄μ λ΄λΆ μ¬λ‘― [[Environment]]
- ν¨μκ° μ μλ νκ²½ (μμΉ) κ³Ό νΈμΆλλ νκ²½(μμΉ) μ λ€λ₯Ό μ μλ€.
- λ μ컬 μ€μ½νκ° κ°λ₯νλ €λ©΄ ν¨μλ μμ μ΄ νΈμΆλλ νκ²½κ³Όλ μκ΄μμ΄ μμ μ΄ μ μλ νκ²½, μ¦ μμ μ€μ½ν (ν¨μ μ μκ° μμΉνλ μ€μ½νκ° λ°λ‘ μμ μ€μ½νμ) λ₯Ό κΈ°μ΅ν΄μΌ ν¨.
- ν¨μκ° μμ μ λ΄λΆ μ¬λ‘― [[Environment]] μ μμ μ΄ μ μλ νκ²½, μ¦ μμ μ€μ½νμ μ°Έμ‘°λ₯Ό μ μ₯νλ€.
- μμ μ λ΄λΆ μ¬λ‘― [[Environment]] μ μ μ₯λ μμ μ€μ½νμ μ°Έμ‘°λ νμ¬ μ€ν μ€μΈ μ€ν 컨ν μ€νΈμ λ μ컬 νκ²½μ κ°λ¦¬ν΄.
- ν¨μ κ°μ²΄μ λ΄λΆ μ¬λ‘― [[Environment]] μ μ μ₯λ νμ¬ μ€ν μ€μΈ μ€ν 컨ν μ€νΈμ λ μ컬 νκ²½μ μ°Έμ‘°κ° λ°λ‘ μμ μ€μ½νλ€.
- λν, μμ μ΄ νΈμΆλμμ λ μμ±λ ν¨μ λ μ컬 νκ²½μ "μΈλΆ λ μ컬 νκ²½μ λν μ°Έμ‘°" μ μ μ₯λ μ°Έμ‘°κ°μ΄λ€.
- ν¨μ κ°μ²΄λ λ΄λΆ μ¬λ‘― [[Environment]] μ μ μ₯ν λ μ컬 νκ²½μ μ°Έμ‘°, μ¦ μμ μ€μ½νλ₯Ό μμ μ΄ μ‘΄μ¬νλ ν κΈ°μ΅νλ€.
const x = 1;
function foo() {
const x = 10;
// μμ μ€μ½νλ ν¨μ μ μ νκ²½ (μμΉ) μ λ°λΌ κ²°μ λ¨.
// ν¨μ νΈμΆ μμΉμ μμ μ€μ½νλ μλ¬΄λ° κ΄κ³κ° μμ
bar();
}
// ν¨μ bar()λ μμ μ μμ μ€μ½ν, μ¦ μ μ λ μ컬 νκ²½μ [[Environment]] μ μ μ₯νμ¬ κΈ°μ΅ν¨.
function bar() {
console.log(x);
}
foo(); //1
bar(); //1
- ν¨μκ° νΈμΆλλ©΄ ν¨μ λ΄λΆλ‘ μ½λμ μ μ΄κΆμ΄ μ΄λνλ€. κ·Έλ¦¬κ³ ν¨μ μ½λλ₯Ό νκ°νκΈ° μμνλ€.
1. ν¨μ μ€ν 컨ν μ€νΈ μμ±
2. ν¨μ λ μ컬 νκ²½ μμ±
γ2.1 ν¨μ νκ²½ λ μ½λ μμ±
γ2.2 this λ°μΈλ©
γ2.3 μΈλΆ λ μ컬 νκ²½μ λν μ°Έμ‘° κ²°μ
μ΄λ, ν¨μ λ μ컬 νκ²½μ κ΅¬μ± μμμΈ μΈλΆ λ μ컬 νκ²½μ λν μ°Έμ‘°μλ ν¨μ κ°μ²΄μ λ΄λΆ μ¬λ‘― [[Environment]] μ μ μ₯λ λ μ컬 νκ²½μ μ°Έμ‘°κ° ν λΉλλ€.
μ¦, ν¨μ κ°μ²΄μ λ΄λΆ μ¬λ‘― [[Environment]] μ μ μ₯λ λ μ컬 νκ²½μ μ°Έμ‘°λ λ°λ‘ ν¨μμ μμ μ€μ½νλ₯Ό μλ―Ένλ€.
μ΄κ²μ΄ λ°λ‘ ν¨μ μ μ μμΉμ λ°λΌ μμ μ€μ½νλ₯Ό κ²°μ νλ λ μ컬 μ€μ½νμ μ€μ²΄μ.
3) ν΄λ‘μ μ λ μ컬 νκ²½
const x = 1;
function outer() {
const x = 10;
const inner = function () { console.log(x); }
return inner;
}
// outer ν¨μλ₯Ό νΈμΆνλ©΄ μ€μ²© ν¨μ inner λ₯Ό λ°ννλ€.
// κ·Έλ¦¬κ³ outer ν¨μμ μ€ν 컨ν
μ€νΈλ μ€ν 컨ν
μ€νΈ μ€νμμ νλμ΄ μ κ±°λλ€.
const innerFunc = outer();
innerFunc(); //10
- μ μ½λμμ outerν¨μλ inner ν¨μλ₯Ό λ°ννκ³ μλͺ μ£ΌκΈ°(life cycle)λ₯Ό λ§κ°νλ€.
- μ¦, outer ν¨μμ μ€νμ΄ μ’ λ£λλ©΄ outer ν¨μμ μ€ν 컨ν μ€νΈλ μ€ν 컨ν μ€νΈ μ€νμμ μ κ±°(pop)λ¨. (outer ν¨μμ λ μ컬 νκ²½μ μλ©Ένμ§ μμ.)
- κ·Έλ κΈ° λλ¬Έμ, inner ν¨μλ (μ€μ²© ν¨μ) outer ν¨μ (μΈλΆ ν¨μ) μ λ³μλ₯Ό μ°Έμ‘°νκ³ μκΈ° λλ¬Έμ μ½λμ μ€ν κ²°κ³Όμμλ μΈλΆ ν¨μμΈ outer ν¨μμ μ§μ λ³μ x μ κ°μΈ 10μ΄ μΆλ ₯λλ€. μ΄λ¬ν μ€μ²© ν¨μλ₯Ό ν΄λ‘μ (closure) λΌκ³ λΆλ¦. π
- ν΄λ‘μ (closure)λ μ€μ²© ν¨μκ° μμ μ€μ½νμ μλ³μλ₯Ό μ°Έκ³ νκ³ μκ³ , μ€μ²© ν¨μκ° μΈλΆ ν¨μλ³΄λ€ λ μ€λ μ μ§λλ κ²½μ°μ νμ νλ κ²μ΄ μΌλ°μ μ.
4) ν΄λ‘μ μ νμ©
- ν΄λ‘μ λ μνλ₯Ό μμ νκ² λ³κ²½νκ³ , μ μ§νκΈ° μν΄ μ¬μ©νλ€.
- μνλ₯Ό μμ νκ² μλ (information hiding) νκ³ νΉμ ν¨μμκ²λ§ μν λ³κ²½μ νμ©νλ€.
// μΉ΄μ΄νΈ μν λ³κ²½ ν¨μ
const increase = (function () {
// μΉ΄μ΄νΈ μν λ³μ
let num = 0;
// ν΄λ‘μ
return function () {
return ++num;
};
}());
console.log(increase()); //1
console.log(increase()); //2
console.log(increase()); //3
- μ μ½λμμλ μ¦μ μ€ν ν¨μκ° νΈμΆλκ³ , μ¦μ μ€ν ν¨μκ° λ°νν ν¨μκ° increase λ³μμ ν λΉλ¨.
- increase λ³μμ ν λΉλ ν¨μλ μμ μ΄ μ μλ μμΉμ μν΄ κ²°μ λ μμ μ€μ½νμΈ μ¦μ μ€ν ν¨μμ λ μ컬 νκ²½μ κΈ°μ΅νλ ν΄λ‘μ λ€.
- μ¦μ μ€ν ν¨μλ ν λ²λ§ μ€νλλ―λ‘ increaseκ° νΈμΆλ λλ§λ€ num λ³μκ° μ¬μ°¨ μ΄κΈ°νλ μΌμ μκ³ , λν num λ³μλ μΈλΆμμ μ§μ μ κ·Όν μ μλ μλλ private λ³μμ΄λ―λ‘ μ μ λ³μλ₯Ό μ¬μ©νμ λμ κ°μ΄ μλλμ§ μμ λ³κ²½μ κ±±μ ν νμλ μκΈ° λλ¬Έμ μμ μ μ΄λ€!
- μ΄μ²λΌ ν΄λ‘μ λ μνκ° μλμΉ μκ² λ³κ²½λμ§ μλλ‘ μμ νκ² μλνκ³ , νΉμ ν¨μμκ²λ§ μν λ³κ²½μ νμ©νμ¬ μνλ₯Ό μμ νκ² λ³κ²½νκ³ , μ μ§νκΈ° μν΄ μ¬μ©ν¨.
const counter = (function () {
// μΉ΄μ΄ν° μν λ³μ
let num = 0;
// ν΄λ‘μ μΈ λ©μλλ₯Ό κ°λ κ°μ²΄λ₯Ό λ°ν
// κ°μ²΄ 리ν°λ΄μ μ€μ½νλ₯Ό λ§λ€μ§ μμ
// λ°λΌμ μλ λ©μλλ€μ μμ μ€μ½νλ μ¦μ μ€ν ν¨μμ λ μ컬 νκ²½μ
return {
// num: 0, νλ‘νΌν°λ pbulic νλ―λ‘ μλλμ§ μμ!
increase() {
return ++num;
},
decrease() {
return num > 0 ? --num : 0;
}
};
}());
console.log(counter.increase()); //1
console.log(counter.increase()); //2
console.log(counter.decrease()); //1
console.log(counter.decrease()); //0
μ μ½λμμ μ¦μ μ€ν ν¨μκ° λ°ννλ κ°μ²΄ 리ν°λ΄μ μ¦μ μ€ν ν¨μμ μ€ν λ¨κ³μμ νκ°λμ΄ κ°μ²΄κ° λ¨.
κ°μ²΄μ λ©μλλ ν¨μ κ°μ²΄λ‘ μμ±λκ³ , κ°μ²΄ 리ν°λ΄μ μ€κ΄νΈλ μ½λ λΈλ‘μ΄ μλλ―λ‘ λ³λμ μ€μ½νλ₯Ό μμ±νμ§ μλλ€.
increase μ decreaseμ μμ μ€μ½νλ λ κ°μ λ©μλκ° νκ°λλ μμ μ μ€ν μ€μΈ μ€ν 컨ν μ€νΈμΈ μ¦μ μ€ν ν¨μ μ€ν 컨ν μ€νΈμ λ μ컬 νκ²½μ΄λ€.
κ·Έλ κΈ° λλ¬Έμ μΈμ μ΄λμ νΈμΆλλ μκ΄μμ΄ μ¦μ μ€ν ν¨μμ μ€μ½νμ μλ³μλ₯Ό μ°Έμ‘°ν μ μμ!
λ³μ κ°μ λκ΅°κ°μ μν΄ μΈμ λ μ§ λ³κ²½λ μ μμ΄ μ€λ₯ λ°μμ κ·Όλ³Έμ μμΈμ΄ λ μ μμ.
μΈλΆ μν λ³κ²½μ΄λ κ°λ³(mutable) λ°μ΄ν°λ₯Ό νΌνκ³ λΆλ³μ±(immutability) μ μ§ν₯νλ ν¨μν νλ‘κ·Έλλ°μμ λΆμ ν¨κ³Όλ₯Ό μ΅λν μ΅μ νμ¬ μ€λ₯λ₯Ό νΌνκ³ νλ‘κ·Έλ¨μ μμ μ±μ λμ΄κΈ° μν΄ ν΄λ‘μ λ μ κ·Ήμ μΌλ‘ μ¬μ©λ¨.
// ν¨μλ₯Ό μΈμλ‘ μ λ¬λ°κ³ ν¨μλ₯Ό λ°ννλ κ³ μ°¨ν¨μ
// μ΄ ν¨μλ μΉ΄μ΄νΈ μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ counter λ₯Ό κΈ°μ΅νλ ν΄λ‘μ λ₯Ό λ°ννλ€.
function makeCounter (predicate) {
// μΉ΄μ΄ν° μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ
let counter = 0;
// ν΄λ‘μ λ₯Ό λ°ν
return function () {
// μΈμλ‘ μ λ¬λ°μ 보쑰 ν¨μμ μν λ³κ²½μ μμνλ€.
counter = predicate(counter);
return counter;
};
}
// 보쑰ν¨μ
function increase2(n) {
return ++n;
}
// 보쑰ν¨μ
function decrease2(n) {
return --n;
}
// ν¨μλ‘ ν¨μλ₯Ό μμ±νλ€.
// makeCounter ν¨μλ 보쑰 ν¨μλ₯Ό μΈμλ‘ μ λ¬λ°μ ν¨μλ₯Ό λ°νν¨
const increaser = makeCounter(increase2);
console.log(increaser()); //1
console.log(increaser()); //2
// increaser ν¨μμλ λ³κ°μ λ
립λ λ μ컬 νκ²½μ κ°κΈ° λλ¬Έμ μΉ΄μ΄ν° μνκ° μ°λλμ§ μμ
const decreaser = makeCounter(decrease2);
console.log(decreaser()); //-1
console.log(decreaser()); //-2
μ μ½λμμ makeCounter ν¨μλ₯Ό νΈμΆν΄ ν¨μλ₯Ό λ°νν λ λ°νλ ν¨μλ μμ λ§μ λ 립λ λ μ컬 νκ²½μ κ°λλΉ.
makeCounter ν¨μκ° λ°νν ν¨μλ makeCounter ν¨μμ λ μ컬 νκ²½μ μμ μ€μ½νλ‘μ κΈ°μ΅νλ ν΄λ‘μ λ€.
makeCounter ν¨μ μ€ν 컨ν μ€νΈμ λ μ컬 νκ²½μ makeCounter ν¨μκ° λ°νν ν¨μμ [[Environment]] λ΄λΆ μ¬λ‘―μ μν΄ μ°Έμ‘°λκ³ μκΈ° λλ¬Έμ μλ©Έλμ§ μμ!!!!!!!
μ μ½λμμλ μ μ λ³μ increaser μ decreaser μ ν λΉλ ν¨μλ κ°κ° μμ λ§μ λ 립λ λ μ컬 νκ²½μ κ°κΈ° λλ¬Έμ μΉ΄μ΄νΈλ₯Ό μ μ§νκΈ° μν μμ λ³μ counter λ₯Ό 곡μ νμ§ μμ μΉ΄μ΄ν°μ μ¦κ°μ΄ μ°λλμ§ μμ! λ°λΌμ, λ μ컬 νκ²½μ 곡μ νλ ν΄λ‘μ λ₯Ό λ§λ€μ΄μΌ ν무λλ€.
//λ
립λ μΉ΄μ΄ν°κ° μλ, μ°λνμ¬ μ¦κ°μ΄ κ°λ₯ν μΉ΄μ΄ν°λ₯Ό λ§λ€λ €λ©΄ λ μ컬 νκ²½μ 곡μ νλ ν΄λ‘μ λ₯Ό λ§λ€μ΄μΌ ν¨.
//ν¨μλ₯Ό λ°ννλ κ³ μ°¨ ν¨μ
//μ΄ ν¨μλ μΉ΄μ΄νΈ μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ counter λ₯Ό κΈ°μ΅νλ ν΄λ‘μ λ₯Ό λ°ννλ€.
const counter2 = (function () {
//μΉ΄μ΄ν° μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ
let counter2 = 0;
//ν¨μλ₯Ό μΈμλ‘ μ λ¬λ°μ ν΄λ‘μ λ₯Ό λ°ν
return function (predicate) {
//μΈμλ‘ μ λ¬λ°μ 보쑰 ν¨μμ μν λ³κ²½μ μμν¨
counter2 = predicate(counter2);
return counter2;
};
}());
//보쑰ν¨μ
function increase3 (n) {
return ++n;
}
//보쑰ν¨μ
function decrease3 (n) {
return --n;
}
//보쑰ν¨μλ₯Ό μ λ¬νμ¬ νΈμΆ
console.log(counter2(increase3));
console.log(counter2(increase3));
console.log(counter2(decrease3));
console.log(counter2(decrease3));
//μμ λ³μλ₯Ό 곡μ νκ³ μλ΅.
κ²°λ‘ .
ν΄λ‘μ λ ν¨μμ ν΄λΉ ν¨μκ° μ μΈλ λ μ컬 νκ²½μ μ‘°ν©!
μΈλΆ ν¨μκ° λ°νλ νμλ μΈλΆ ν¨μμ λ³μ λ²μ 체μΈμ μ κ·Όν μ μλ ν¨μλ€!
μ μ λ³μμ μ¬μ©μ μ΅μ νκ³ , μ 보λ₯Ό μλνκΈ° μν΄ μ¬μ©νλ€λ κ²μ΄λ€. π
'JavaScript π' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
null κ³Ό undefined μ μ°¨μ΄μ (0) | 2022.12.21 |
---|---|
μ΄λ²€νΈ 루νμ νμ€ν¬ ν (0) | 2022.12.18 |
λκΈ°/λΉλκΈ° (0) | 2022.12.10 |
νΈμ΄μ€ν (hoisting) (0) | 2022.12.09 |
Truthyμ Falsy (0) | 2022.11.30 |