
๐ป
closure์scope์ ๋ํด ๊ตฌ์ฒด์ ์ผ๋ก ์ดํดํ๋ ๊ฒ์ด JavaScript ์ด๋ณด์์ ์๋ จ์๋ฅผ ๊ฐ๋ฅด๋ ๊ธฐ์ค๋ค ์ค ํ๋์ด๋ค.
Scope์ ์๋ฏธ์ ์ ์ฉ ๋ฒ์๋ฅผ ์ดํดํ ์ ์๋คScope ์ฃผ์ ๊ท์น์ ์ดํดํ ์ ์๋คlet, const, var์ ์ฐจ์ดScope : ๋ณ์ ์ ๊ทผ ๊ท์น์ ๋ฐ๋ฅธ ์ ํจ ๋ฒ์lexical) ๋์์Scope๋ฅผ ๊ฐ์ง๋ค.let greeting = 'Hello';
function greetSomeone() {
let firstName = 'Josh';
return greeting + ' ' + firstName;
}
greetSomeone(); // "Hello Josh"
firstName; // ReferenceError
Scope์์ ๋ฐ๊นฅ ๋ณ์/ํจ์์ ์ ๊ทผํ๋ ๊ฒ์ ๊ฐ๋ฅScope์์ ์์ชฝ ๋ณ์/ํจ์์ ์ ๊ทผํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅ
Scope๋ ์ค์ฒฉ์ด ๊ฐ๋ฅํ๋ค.Global Scope๋ ์ต์๋จ์ Scope๋ก, ์ ์ญ ๋ณ์๋ ์ด๋์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.let name = "Richard";
function showName() {
let name = "Jack"; // ์ง์ญ ๋ณ์
// showName ํจ์ ์์์๋ง ์ ๊ทผ ๊ฐ๋ฅ
console.log(name); // Jack
}
console.log(name); // Richard
showName();
console.log(name); // Richard
let name = "Richard";
function showName() {
name = "Jack"; // ์ ์ญ ๋ณ์
// ์ ์ธ(let)์ด ์๊ธฐ ๋๋ฌธ์, ๋ฐ๊นฅ scope์ ์๋ name์ด๋ผ๋ ๋ณ์๋ฅผ ๊ฐ์ ธ์ด
console.log(name); // Jack
}
console.log(name); // Richard
showName();
console.log(name); // Jack
JavaScript๋ ๊ธฐ๋ณธ์ ์ผ๋ก, ํจ์ ๋จ์๋ก ์์ ๋ง์ Scope๋ฅผ ๊ฐ์ง๋ค. var ํค์๋ : old wayBlock ๋จ์๋ก Scope๋ฅผ ๊ตฌ๋ถํ์ ๋์ ์์ธกํ๊ธฐ ์ฌ์ด ์ฝ๋let ํค์๋Block : ์ค๊ดํธ๋ก ์์ํ๊ณ , ๋๋๋ ๋จ์for (let i = 0; i < 5; i++) {
console.log(i); // ๋ค์ฏ๋ฒ iteration
}
console.log('final i:', i);
// ReferenceError
-> block ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ์ฆ์ ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
-> var ํค์๋๋ฅผ ์ฌ์ฉํด์ ๋ณ์๋ฅผ ์ ์ธํ์ผ๋ฏ๋ก,
for (var i = 0; i < 5; i++) {
console.log(i); // ๋ค์ฏ๋ฒ iteration
}
console.log('final i:', i); // 5
-> block ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ (๊ฐ์ function scope ์์๋) ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
constlet ํค์๋์ ๋์ผํ๊ฒ Block Scope๋ฅผ ๋ฐ๋ฅธ๋ค.TypeError๋ฅผ ๋ธ๋ค.
windowGlobal Scope์์ ์ ์ธ๋ ํจ์, ๊ทธ๋ฆฌ๊ณ var ํค์๋๋ฅผ ์ด์ฉํด ์ window ๊ฐ์ฒด์ ์ฐ๊ฒฐvar myName = "Paul";
console.log(window.myName); // Paul
function foo() {
console.log('bar');
}
console.log(foo === window.foo); // true
var, let, const) ์์ด ๋ณ์๋ฅผ ์ด๊ธฐํํ์ง ๋ง์์ผ ํ๋ค.Closure์ ์๋ฏธ์ Closure๊ฐ ๊ฐ์ง๋ Scope Chain์ ์ดํดํ ์ ์๋ค.Closure์ ์ ์ฉํ๊ฒ ์ฐ์ด๋ ๋ช ๊ฐ์ง ์ฝ๋ฉ ํจํด์ ์ดํดํ ์ ์๋ค.innerVar), ์ธ๋ถ ํจ์์ ๋ณ์(outerVar), ์ ์ญ ๋ณ์(globalVar)์ ์ ๊ทผ์ด ๋ชจ๋ ๊ฐ๋ฅํ๋ค.function outerFn() {
let outerVar = 'outer';
console.log(outerVar);
function innerFn() {
let innerVar = 'inner';
console.log(innerVar);
}
return innerFn;
}
outerFn();
outerVar์ ๊ฐ์ด ์ฐํ๊ณ , ์์ง ์คํ๋์ง ์์ ํจ์(innerFn)๊ฐ ๋ฆฌํด๋๋ค.
function outerFn() {
let outerVar = 'outer';
console.log(outerVar);
function innerFn() {
let innerVar = 'inner';
console.log(innerVar);
}
return innerFn;
}
outerFn()(); // 1
let innerFn = outerFn(); // 2
innerFn(); // 3
์ธ๋ถ ํจ์์ ๋ด๋ถ ํจ์๋ฅผ ์ฐ๋ฌ์ ํธ์ถํ๋ค.

์ธ๋ถ ํจ์์ ๋ฆฌํด๊ฐ์ innerFn์ด๋ผ๋ ๋ณ์์ ๋ด๋๋ค.

๋ด๋ถ ํจ์๊ฐ ๋ด๊ธด innerFn์ ํธ์ถํ๋ค.

function adder(x) {
return function(y) {
return x + y;
}
}
adder(2)(3); // 5
let add100 = adder(100); // x์ ๊ฐ์ ๊ณ ์ ํด๋๊ณ ์ฌ์ฌ์ฉํ ์ ์๋ค
add100(2); // 102
add100(10); // 110
let add5 = adder(5);
add5(2); // 7
function htmlMaker(tag) {
let startTag = '<' + tag + '>';
let endTag = '</' + tag + '>';
return function(content) {
return startTag + content + endTag;
}
}
let divMaker = htmlMaker('div');
divMaker('nayce'); // <div>nayce</div>
let h1Maker = htmlMaker('h1');
h1Maker('Headline'); // <h1>Headline</h1>
function makeCounter() {
let privateCounter = 0;
return {
increment: function() {
privateCounter++;
},
decrement: function() {
privateCounter--;
},
getValue: function() {
return privateCounter;
}
}
}
let counter1 = makeCounter();
counter1.increment();
counter1.increment();
counter1.getValue(); // 2
let counter2 = makeCounter();
counter2.increment();
counter2.decrement();
counter2.increment();
counter2.getValue(); // 1
-> ๋ ์นด์ดํฐ์ ๊ฐ๊ธฐ ๋ค๋ฅธ privateCounter๋ฅผ ๋ค๋ฃจ๋ฉด์, privateCounter๋ฅผ ๋ฐ์ผ๋ก ๋
ธ์ถ์ํค์ง ์๋๋ค.