βοΈ μ΄λ² μ λ μ ν΅ν΄ μκ² λ κ²
ν΄λ‘μ λ 무μμΈκ°μ?
λ μ컬 μ€μ½νκ° λ¬΄μμΈκ°μ?
<λ΅ λ―Έλ¦¬λ³΄κΈ°>
π€ ν΄λ‘μ λ 무μμΈκ°μ?
π€ ν΄λ‘μ λ ν¨μμ κ·Έ ν¨μκ° μ μΈλ λ μ컬 νκ²½κ³Όμ μ‘°ν©μ λλ€.
π€ λ μ컬 μ€μ½νκ° λ¬΄μμΈκ°μ?
π€ μλ°μ€ν¬λ¦½νΈ μμ§μ ν¨μλ₯Ό μ΄λμ μ μνλμ§μ λ°λΌ μμ μ€μ½νλ₯Ό κ²°μ νλλ° μ΄λ₯Ό λ μ컬 μ€μ½νλΌκ³ ν©λλ€.
βοΈ ν΄λ‘μ λ
ν΄λ‘μ λ μλ°μ€ν¬λ¦½νΈ κ³ μ μ κ°λ μ΄ μλλ€. ν¨μλ₯Ό μΌκΈ κ°μ²΄λ‘ μ·¨κΈνλ ν¨μν νλ‘κ·Έλλ° μΈμ΄μμ μ¬μ©λλ νΉμ±μ΄λ€.
ν΄λ‘μ in MDN
π A closure is the combination of a function and the lexical environment within which that function was declared.
ν΄λ‘μ λ ν¨μμ κ·Έ ν¨μκ° μ μΈλ λ μ컬 νκ²½κ³Όμ μ‘°ν©μ΄λ€.
const x = 1;
function outerFunc() {
const x = 10;
function innerFunc() {
console.log(x); // 10
}
innerFunc();
}
outerFunc();
→ outer ν¨μ λ΄λΆμμ μ€μ²© ν¨μ(inner)κ° μ μλκ³ νΈμΆλμλ€.
μ΄λ inner ν¨μμ μμ μ€μ½νλ μΈλΆ ν¨μ outer ν¨μμ μ€μ½νμ΄λ€. λ°λΌμ inner λ΄λΆμμ μμ μ ν¬ν¨νκ³ μλ μΈλΆ ν¨μ outer ν¨μμ x λ³μμ μ κ·Όν μ μλ€.
=> μλ°μ€ν¬λ¦½νΈλ λ μ컬 μ€μ½νλ₯Ό λ°λ₯΄λ νλ‘κ·Έλλ° μΈμ΄μ΄λ€.
βοΈ λ μ컬 μ€μ½νλ
μλ°μ€ν¬λ¦½νΈ μμ§μ ν¨μλ₯Ό μ΄λμ νΈμΆνλμ§κ° μλλΌ ν¨μλ₯Ό μ΄λμ μ μνλμ§μ λ°λΌ μμ μ€μ½νλ₯Ό κ²°μ ν©λλ€.
λ μ컬 νκ²½μ 'μΈλΆ λ μ컬 νκ²½μ λν μ°Έμ‘°'μ μ μ₯ν μ°Έμ‘°κ°, μ¦ μμ μ€μ½νμ λν μ°Έμ‘°λ ν¨μ μ μκ° νκ°λλ μμ μ ν¨μκ° μ μλ νκ²½μ μν΄ κ²°μ λ©λλ€.
(... μ΄ν΄λ νμ§λ§ λ¨μκ² μ€λͺ ν λ§νΌ λͺ ννκ² μ΄ν΄λ λͺ»ν¨...)
βοΈ ν¨μ κ°μ²΄μ λ΄λΆ μ¬λ‘―
ν¨μκ° μ μλ νκ²½(μμΉ)κ³Ό νΈμΆλλ νκ²½(μμΉ)λ λ€λ₯Ό μ μλ€.
κ·Έλμ λ μ컬 μ€μ½νκ° κ°λ₯νλ €λ©΄ ν¨μλ μμ μ΄ μ μλ νκ²½, μ¦ μμ μ€μ½ν(ν¨μ μ μκ° μμΉνλ μ€μ½ν)λ₯Ό κΈ°μ΅ν΄μΌ νλ€. μ΄λ₯Ό μν΄μ ν¨μλ μμ μ λ΄λΆ μ¬λ‘―μ μμ μ΄ μ μλ νκ²½, μ¦ μμ μ€μ½νμ μ°Έμ‘°λ₯Ό μ μ₯νλ€.
const x = 1;
function foo() {
const x = 10;
// μμ μ€μ½νλ ν¨μ μ μ νκ²½(μμΉ)μ λ°λΌ κ²°μ λλ€.
// ν¨μ νΈμΆ μμΉμ μμ μ€μ½νλ μλ¬΄λ° κ΄κ³κ° μλ€.
bar();
}
// ν¨μ barλ μμ μ μμ μ€μ½ν, μ¦ μ μ λ μ컬 νκ²½μ [[Environment]]μ μ μ₯νμ¬ κΈ°μ΅νλ€.
function bar() {
console.log(x);
}
foo(); // 1
bar(); // 1
βοΈ ν΄λ‘μ μ λ μ컬 νκ²½
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 ν¨μλ₯Ό 리ν΄νκ³ μ€ν 컨ν μ€νΈ μ€νμμ μ κ±°λλ€. μλλ©΄ μλͺ μ£ΌκΈ°κ° λ§κ°λμκΈ° λλ¬Έμ!
κ·Έλμ μΌν보기μ outerν¨μμ μ§μλ³μ xκ° μ ν¨νμ§ μμ κ²μ²λΌ λ³΄μΌ μ μλλ° μ€μ μλλ€!
μλλ©΄
μΈλΆν¨μλ³΄λ€ μ€μ²© ν¨μκ° λ μ€λ μ μ§λλ κ²½μ°,
μ€μ²©ν¨μλ μ΄λ―Έ μλͺ μ£ΌκΈ°κ° μ’ λ£ν μΈλΆ ν¨μμ λ³μλ₯Ό μ°Έμ‘°ν μ μκΈ° λλ¬Έμ΄λ€.
(μ΄κ² λ°λ‘ ν΄λ‘μ closure)
outerν¨μμ μ€ν 컨ν μ€νΈλ μ€ν 컨ν μ€νΈ μ€νμμ μ κ±°λμ§λ§ outer ν¨μμ λ μ컬 νκ²½κΉμ§ μλ©Ένλ건 μλλ€!!
outer ν¨μμ λ μ컬 νκ²½μ inner ν¨μμ λ΄λΆ μ¬λ‘―μ μν΄ μ°Έμ‘°λκ³ μκ³ , inner ν¨μλ μ μλ³μ innerFuncμ μν΄ μ°Έμ‘°λκ³ μμΌλ―λ‘ κ°λΉμ§ 컬λ μ μ λμμ΄ λμ§ μκΈ° λλ¬Έμ΄λ€.
(κ°λΉμ§ 컬λ ν°λ λκ΅°κ° μ°Έμ‘°νκ³ μλ λ©λͺ¨λ¦¬ 곡κ°μ ν¨λΆλ‘ ν΄μ νμ§ μλλ€. )
βοΈ ν΄λ‘μ κ° μλ ν¨μ
μλ°μ€ν¬λ¦½νΈμ λͺ¨λ ν¨μλ μμ μ€μ½νλ₯Ό κΈ°μ΅νλ―λ‘ μ΄λ‘ μ μΌλ‘ λͺ¨λ ν¨μλ ν΄λ‘μ μ΄λ€. νμ§λ§ μΌλ°μ μΌλ‘ λͺ¨λ ν¨μλ₯Ό ν΄λ‘μ λΌκ³ νμ§ μλλ€.
1. μμ μ€μ½νμ μλ³μλ₯Ό μ°Έμ‘°νμ§ μμΌλ©΄ ν΄λ‘μ κ° μλλ€.
2. μΈλΆν¨μλ³΄λ€ μ€μ²©ν¨μμ μλͺ μ£ΌκΈ°κ° μ§§μΌλ©΄ κ·Έ μ€μ²©ν¨μλ ν΄λ‘μ κ° μλλ€.
ν΄λ‘μ λ μ€μ²© ν¨μκ° μμ μ€μ½νμ μλ³μλ₯Ό μ°Έμ‘°νκ³ μκ³ ,
μ€μ²© ν¨μκ° μΈλΆ ν¨μλ³΄λ€ λ μ€λ μ μ§λλ κ²½μ°μ νμ νλ κ²μ΄ μΌλ°μ μ΄λ€.
βοΈ ν΄λ‘μ μ λ¨μ ?!
ν΄λ‘μ λ μμ μ€μ½νλ₯Ό κΈ°μ΅ν΄μΌ νλ―λ‘ λΆνμν λ©λͺ¨λ¦¬μ μ μ λ₯Ό κ±±μ ν μλ μκ² μ§λ§,
λͺ¨λ μλ°μ€ν¬λ¦½νΈ μμ§μ μ΅μ νκ° μ λμ΄ μμ΄μ ν΄λ‘μ κ° μ°Έμ‘°νκ³ μμ§ μλ μλ³μλ κΈ°μ΅νμ§ μλλ€κ³ νλ€.
κ·Έλμ ν΄λ‘μ μ λ©λͺ¨λ¦¬ μ μ μ λν΄ κ±±μ ν νμ μκ³ , νμνλ€λ©΄ ν΄λ‘μ λ₯Ό μ κ·Ή νμ©ν΄λ³΄μ!!
βοΈ ν΄λ‘μ μ νμ©
ν΄λ‘μ λ μνκ° μλμΉ μκ² λ³κ²½λμ§ μλλ‘ μνλ₯Ό μμ νκ² μλνκ³ νΉμ ν¨μμκ²λ§ μν λ³κ²½μ νμ©νκΈ° μν΄ μ¬μ©νλ€.
νΉν μΈλΆ μν λ³κ²½μ΄λ λΆλ³μ±μ μ§ν₯νλ ν¨μν νλ‘κ·Έλλ°μμ λΆμ ν¨κ³Όλ₯Ό μ΅λν μ΅μ ν΄μ μ€λ₯λ₯Ό νΌνκ³ νλ‘κ·Έλ¨μ μμ μ±μ λμ΄κΈ° μν΄ ν΄λ‘μ λ μ κ·Ήμ μΌλ‘ μ¬μ©λλ€.
// ν¨μλ₯Ό μΈμλ‘ μ λ¬λ°κ³ ν¨μλ₯Ό λ°ννλ κ³ μ°¨ ν¨μ
// μ΄ ν¨μλ μΉ΄μ΄νΈ μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ counterλ₯Ό κΈ°μ΅νλ ν΄λ‘μ λ₯Ό λ°ννλ€.
function makeCounter(aux) {
// μΉ΄μ΄νΈ μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ
let counter = 0;
// ν΄λ‘μ λ₯Ό λ°ν
return function () {
// μΈμλ‘ μ λ¬ λ°μ 보쑰 ν¨μμ μν λ³κ²½μ μμνλ€.
counter = aux(counter);
return counter;
};
}
// 보쑰 ν¨μ
function increase(n) {
return ++n;
}
// 보쑰 ν¨μ
function decrease(n) {
return --n;
}
// ν¨μλ‘ ν¨μλ₯Ό μμ±νλ€.
// makeCounter ν¨μλ 보쑰 ν¨μλ₯Ό μΈμλ‘ μ λ¬λ°μ ν¨μλ₯Ό λ°ννλ€
const increaser = makeCounter(increase); // β
console.log(increaser()); // 1
console.log(increaser()); // 2
// increaser ν¨μμλ λ³κ°μ λ
립λ λ μ컬 νκ²½μ κ°κΈ° λλ¬Έμ μΉ΄μ΄ν° μνκ° μ°λνμ§ μλλ€.
const decreaser = makeCounter(decrease); // β‘
console.log(decreaser()); // -1
console.log(decreaser()); // -2
π μ¬κΈ°μ makeCounter ν¨μκ° λ°ννλ ν¨μλ μμ μ΄ μμ±λμμ λμ λ μ컬 νκ²½μΈ makeCounterν¨μμ μ€μ½νμ μν counter λ³μλ₯Ό κΈ°μ΅νλ ν΄λ‘μ μ΄λ€.
κ·Έλ°λ° μ΄ ν¨μλ μμ λ§μ λ 립λ λ μ컬 νκ²½μ κ°μ Έμ, νΈμΆν λλ§λ€ μλ‘μ΄ makeCounter ν¨μ μ€ν 컨ν μ€νΈμ λ μ컬 νκ²½μ΄ μμ±λλ€.
// ν¨μλ₯Ό λ°ννλ κ³ μ°¨ ν¨μ
// μ΄ ν¨μλ μΉ΄μ΄νΈ μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ counterλ₯Ό κΈ°μ΅νλ ν΄λ‘μ λ₯Ό λ°ννλ€.
const counter = (function () {
// μΉ΄μ΄νΈ μνλ₯Ό μ μ§νκΈ° μν μμ λ³μ
let counter = 0;
// ν¨μλ₯Ό μΈμλ‘ μ λ¬λ°λ ν΄λ‘μ λ₯Ό λ°ν
return function (aux) {
// μΈμλ‘ μ λ¬ λ°μ 보쑰 ν¨μμ μν λ³κ²½μ μμνλ€.
counter = aux(counter);
return counter;
};
}());
// 보쑰 ν¨μ
function increase(n) {
return ++n;
}
// 보쑰 ν¨μ
function decrease(n) {
return --n;
}
// 보쑰 ν¨μλ₯Ό μ λ¬νμ¬ νΈμΆ
console.log(counter(increase)); // 1
console.log(counter(increase)); // 2
// μμ λ³μλ₯Ό 곡μ νλ€.
console.log(counter(decrease)); // 1
console.log(counter(decrease)); // 0
π λ μ컬 νκ²½μ 곡μ νλ ν΄λ‘μ μ΄λ€.
βοΈ μΊ‘μνμ μ 보 μλ
μΊ‘μνλ κ°μ²΄μ νλ‘νΌν°μ λ©μλλ₯Ό νλλ‘ λ¬Άλ κ²μ λ§νλ€.
μΊ‘μνλ κ°μ²΄μ νΉμ νλ‘νΌν°λ λ©μλλ₯Ό κ°μΆ λͺ©μ μΌλ‘ μ¬μ©νκΈ°λ νλλ° μ΄λ₯Ό μ 보 μλμ΄λΌκ³ νλ€.
π©π» λͺ¨λ μλ°μ€ν¬λ¦½νΈ Deep Diveλ₯Ό μ λ νκ³ μ κ° μ΄ν΄ν λ΄μ©μ μ 리ν κΈμ λλ€ π©π»
'πLanguage > JavaScript' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Deep Dive] DOMκ³Ό λ Έλ (0) | 2022.12.15 |
---|---|
[Deep Dive] λΈλΌμ°μ μ λ λλ§ κ³Όμ (0) | 2022.12.14 |
[Deep Dive] this (0) | 2022.12.07 |
[Deep Dive] var, let, const ν€μλλ₯Ό νν€μ³λ³΄μ (0) | 2022.12.07 |
[Deep Dive] μ€ν 컨ν μ€νΈ (0) | 2022.12.05 |