JavaScript ν΄λ‘μ (Closure)
π¦ Cukehater
Β·2λ μ
MDNμμλ ν΄λ‘μ λ₯Ό "μ£Όλ³ μν(μ΄νμ νκ²½)μ λν μ°Έμ‘°μ ν¨κ» λ¬ΆμΈ(ν¬ν¨λ) ν¨μμ μ‘°ν©μ΄λ©°, μ΄λ₯Ό ν΅ν΄ μΈλΆ ν¨μμ μ€νμ΄ μ’ λ£λλλΌλ λ΄λΆ ν¨μμμ μΈλΆ ν¨μμ λ²μμ λν μ κ·Όμ μ 곡νλ€." λΌκ³ μ€λͺ νλ€. νμ§λ§ μ€λͺ λ§μΌλ‘λ μ λλ‘ μ΄ν΄κ° λμ§ μμκ³ μ΄λ₯Ό νμ€ν μκΈ° μν΄ μ΄ κΈμ ν¬μ€ν νλ€.
TL;DR
ν΄λ‘μ λ ν¨μκ° μ μΈλ λμ νκ²½μ κΈ°μ΅νμ¬, ν¨μ λ΄λΆμμ μ μΈλ λ³μκ° ν¨μ μΈλΆμμ μ°Έμ‘°(μ κ·Ό) κ°λ₯νλλ‘ λ§λλ λ©μ»€λμ¦μ΄λ€.
ν΄λ‘μ μ νΉμ§μ λ€μκ³Ό κ°λ€.
- λ°μ΄ν° 보쑴 λ° μλν κ°λ₯
- λͺ¨λνμ μ 리
- private λ³μ ꡬν κ°λ₯
- μλͺ» μ¬μ© μ λ©λͺ¨λ¦¬ λμ λ°μ κ°λ₯
- κ°λΉμ§ 컬λ μ μ²λ¦¬κ° 볡μ‘
ν΄λ‘μ μ κΈ°λ³Έ κ°λ
MDNμ μ€λͺ λλ‘ ν΄λ‘μ λ₯Ό ν μ€λ‘ μ€λͺ νμλ©΄ ν¨μ λ΄λΆμμ μ μΈλ λ³μκ° ν¨μ μΈλΆμμ μ°Έμ‘° κ°λ₯νλλ‘ λ§λλ λ©μ»€λμ¦μ΄λ€.
μμ λ₯Ό ν΅ν΄ ν΄λ‘μ μ κΈ°λ³Έ κ°λ μ μμ보μ.
javascript
function outer() {
let a = 10;
console.log(a);
}
outer(); // 10
console.log(a); // ReferenceError
μ΄ μ½λμμ ν¨μ outer()
λ΄λΆμμ μ μΈλ λ³μ a
λ ν¨μ λ΄λΆμμλ§ μ κ·Όμ΄ κ°λ₯νλ€. outer()
κ° μ’
λ£λ ν μ μμμ a
μ μ κ·Όνλ €κ³ νλ©΄ λΉμ°νλ ReferenceErrorκ° λ°μνλλ°, μ΄λ a
κ° ν¨μμ μ€ν 컨ν
μ€νΈ λ΄μλ§ μ ν¨νκΈ° λλ¬Έμ΄λ€.
κ·Έλ¬λ ν΄λ‘μ λ₯Ό νμ©νλ©΄ μΈλΆ ν¨μ λ΄λΆμ μλ λ³μμ ν¨μ μΈλΆμμλ μ κ·Όν μ μλ€.
javascript
function outer() {
let a = 10;
return function inner() {
return a;
};
}
let fn1 = outer();
console.log(fn1()); // 10
μ΄ μμ μμ ν¨μ outer()
λ inner()
ν¨μλ₯Ό λ°ννλ€. inner()
λ μΈλΆ ν¨μμΈ outer()
μ λ³μ a
μ μ κ·Όν μ μλ€. μ΄λ inner()
κ° μ μΈλ λμ μ΄νμ νκ²½μ κΈ°μ΅νκΈ° λλ¬Έμ΄λ€.
λ°λΌμ outer()
λ₯Ό ν λΉν ν¨μ fn1()
μμ outer()
ν¨μ λ΄λΆμ λ³μ a
μ μ κ·Όμ΄ κ°λ₯ν΄μ§λ©° 10
μ λ°ννλ€.
μ΄λ¬ν λμμ΄ κ°λ₯ν μ΄μ λ JavaScriptμ λ μ컬 μ€μ½ν(Lexical Scope) νΉμ± λλ¬Έμ΄λ€.
ν¨μκ° μ μΈλ λ κ·Έ ν¨μμ μμ μ€μ½νκ° κ²°μ λλ©°, μ΄ μ€μ½ν 체μΈμ ν΅ν΄ λ³μλ₯Ό μ°Ύμλκ°λ€. inner()
ν¨μκ° μ μΈλ λ outer()
ν¨μμ μ€μ½νλ₯Ό κΈ°μ΅νκ³ μκΈ° λλ¬Έμ, outer()
ν¨μκ° μ€νμ λ§μΉκ³ μ½ μ€νμμ μ κ±°λ νμλ inner()
ν¨μλ μ¬μ ν outer()
ν¨μμ λ³μ a
μ μ κ·Όν μ μλ€.
μ΄λ₯Ό νμ©νλ©΄ λ€μκ³Ό κ°μ μμ λ κ°λ₯νλ€.
javascript
function counter() {
let count = 0;
return {
increase: function() {
return ++count;
},
decrease: function() {
return --count;
},
getCount: function() {
return count;
}
};
}
const counter1 = counter();
console.log(counter1.increase()); // 1
console.log(counter1.increase()); // 2
console.log(counter1.decrease()); // 1
console.log(counter1.getCount()); // 1
μ΄ μμ μμλ counter()
ν¨μκ° μΈ κ°μ λ©μλλ₯Ό κ°μ§ κ°μ²΄λ₯Ό λ°ννλ€.
κ° λ©μλλ ν΄λ‘μ λ₯Ό νμ±νμ¬ count
λ³μμ μ κ·Όν μ μλ€. μ΄λ₯Ό ν΅ν΄ private λ³μμ²λΌ μΈλΆμμ μ§μ μ μΈ μ κ·Όμ λΆκ°λ₯νμ§λ§, μ μλ λ©μλλ₯Ό ν΅ν΄μλ§ μ‘°μμ΄ κ°λ₯ν μλνλ μνλ₯Ό λ§λ€ μ μλ€.
μ΄μ²λΌ ν΄λ‘μ λ λ°μ΄ν° νλΌμ΄λ²μλ₯Ό ꡬννκ³ , μνλ₯Ό μμ νκ² κ΄λ¦¬νλ©°, λͺ¨λνλ μ½λλ₯Ό μμ±νλ λ° λ§€μ° μ μ©ν JavaScriptμ ν΅μ¬ κ°λ μ΄λ€.
ν΄λ‘μ μ μ₯λ¨μ
- λ°μ΄ν° 보쑴
μΈλΆ ν¨μμ μ€νμ΄ λλλλΌλ μΈλΆ ν¨μ λ΄ λ³μλ₯Ό κ³μ μ¬μ©ν μ μλ νΉμ±μ ν΅ν΄ νΉμ λ°μ΄ν°λ₯Ό μ€μ½ν μμ κ°λμ΄ κ³μ μ¬μ©ν μ μλ νμμ±μ κ°λλ€. - λͺ¨λνμ μ 리
ν¨μλ₯Ό λ 립μ μΈ ννλ‘ λΆλ¦¬νμ¬ ν¨μμ μ¬μ¬μ©μ±μ ν₯μμν¬ μ μλ€. μ΄λ₯Ό ν΅ν΄ μ½λμ λͺ¨λνκ° μ©μ΄ν΄μ§λ€. - μ 보μ μλν
μ μΈ λΉμ μ°Έμ‘°νλ μΈλΆ νκ²½μ κΈ°μ΅νμ¬ μ 보 μλμ΄ κ°λ₯νλ€. μ΄λ₯Ό ν΅ν΄ μΈλΆλ‘λΆν°μ μ€μΌμ λ°©μ§ν μ μλ€. - λ©λͺ¨λ¦¬ λμ
μ λλ‘ μ¬μ©λμ§ μμΌλ©΄ λ΄λΆ ν¨μκ° λ μ΄μ μ°Έμ‘°λμ§ μμ λκΉμ§ μΈλΆ ν¨μ λ²μμ λ³μκ° λ©λͺ¨λ¦¬μμ μ§μμ§μ§ μκΈ° λλ¬Έμ λ©λͺ¨λ¦¬ λμλ₯Ό μΌμΌν¬ μ μλ€. λ°λΌμ 루νλ₯Ό λλ©΄μ ν΄λ‘μ λ₯Ό κ³μ μμ±νλ μ€κ³λ μ§μν΄μΌ νλ€. - κ°λΉμ§ 컬λ μ
μ μ΄λ €μ
ν΄λ‘μ μ μ§μμ μΈ νΉμ±μΌλ‘ μΈν΄ κ°λΉμ§ 컬λ ν°κ° ν΄λ‘μ κ° λ μ΄μ νμνμ§ μκ³ λ©λͺ¨λ¦¬μμ μμ νκ² μ κ±°ν μ μλ μκΈ°λ₯Ό κ²°μ νκΈ° μ΄λ €μΈ μ μλ€.
Reactμμ ν΄λ‘μ
Reactμ λ΄μ₯ ν
(Hooks)κ³Ό ν΄λ‘μ λ μλ‘ λ°μ ν μ°κ΄μ΄ μλ€. κ·Έ μ€ useState
ν
μ λμ μ리λ₯Ό ν΄λ‘μ κ΄μ μμ μ΄ν΄λ³΄μ.
jsx
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
useState
λ ν΄λ‘μ λ₯Ό νμ©νμ¬ μ»΄ν¬λνΈμ μνλ₯Ό κ΄λ¦¬νλ€.
Reactλ λ΄λΆμ μΌλ‘ λ€μκ³Ό κ°μ ν΄λ‘μ ꡬ쑰λ₯Ό κ°μ§λ€.
javascript
// React λ΄λΆ λμ λ¨μν μμ
function useState(initialValue) {
let state = initialValue; // ν΄λ‘μ λ₯Ό ν΅ν΄ μ μ§λλ κ°
const setState = (newValue) => {
state = newValue;
// 리λ λλ§ νΈλ¦¬κ±°
};
return [state, setState];
}
μ΄ μ½λμμ μ£Όλͺ©ν μ μ state
λ³μκ° ν΄λ‘μ λ₯Ό ν΅ν΄ μ μ§λλ€λ κ²μ΄λ€. μ»΄ν¬λνΈκ° 리λ λλ§λλλΌλ state
λ³μλ ν΄λ‘μ λλΆμ μ΄μ κ°μ μ μ§ν μ μλ€. λν κ° μ»΄ν¬λνΈ μΈμ€ν΄μ€λ μμ λ§μ ν΄λ‘μ λ₯Ό κ°μ§λ―λ‘, μλ‘ λ€λ₯Έ μ»΄ν¬λνΈμ μνκ° λ
립μ μΌλ‘ μ μ§λλ€.
jsx
function App() {
return (
<div>
<Counter /> {/* λ
립λ state */}
<Counter /> {/* λ
립λ state */}
</div>
);
}
μ΄μ²λΌ ν΄λ‘μ λ Reactμ μ μΈμ μ΄κ³ μμΈ‘ κ°λ₯ν μν κ΄λ¦¬λ₯Ό κ°λ₯νκ² νλ©°, Reactμ μν κ΄λ¦¬ μμ€ν μ ν΅μ¬ λ©μ»€λμ¦μΌλ‘μ, μ»΄ν¬λνΈμ μλͺ μ£ΌκΈ° λμ μνλ₯Ό μμ νκ² λ³΄μ‘΄νκ³ μ λ°μ΄νΈνλ μν μ νλ€.

π¦ Cukehater
κ°λ° κ²½νκ³Ό κΈ°μ μ μΈμ¬μ΄νΈλ₯Ό 곡μ ν©λλ€ π»β¨