
์ค์ฝํ๋, ๋ณ์ ์ด๋ฆ, ํจ์ ์ด๋ฆ, ํด๋์ค ์ด๋ฆ๊ณผ ๊ฐ์ ์๋ณ์๊ฐ ๋ณธ์ธ์ด ์ ์ธ๋ ์์น์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฝ๋์์ ์์ ์ด ์ฐธ์กฐ๋ ์ ์์์ง ์์์ง ๊ฒฐ์ ํ๋ ๊ฒ์ด๋ค. ์๋ณ์์ ๋ํ ์ ํจ๋ฒ์๋ผ๊ณ ๋ ๊ฐ๋จํ ๋งํ๋ค.
ํฌ๋กฌ ๋๋ฒ๊ฑฐ๋ก ๋ณด๋ ์ค์ฝํ
var globalVariable1 = 1;
const globalVariable2 = 2;
const outerConst = function () {
console.log();
};
var outerVar = function () {
console.log();
};
function outerFunc2() {
console.log();
}
function outerFunc1() {
let outerVariable = 999;
function innerFunc() {
const innerVariable = 1;
outerVariable += 1;
}
inner();
}

์ค์ฝํ๋ ์ปจํ ์คํธ์์ ์ ๊ทผํ ์ ์๋ ์๋ณ์๋ค์ ๋ํ๋ด๋ ๊ฒ์ด๋ค. ์์ ์ฌ์ง์ innerFunc() ์ปจํ ์คํธ์์ ์ ๊ทผํ ์ ์๋ ์๋ณ์๋ค์ ์ค์ฝํ๋ณ๋ก ๋ชจ์๋์ ๊ฒ์ด๋ค. (anonymous) ์ปจํ ์คํธ๋ ์ ์ญ ์ปจํ ์คํธ๋ฅผ ๋ปํ๋ค.

๋ด๊ฐ ๊ถ๊ธํ๋ ๊ฒ
Q. ์ปจํ ์คํธ๊ฐ ์๊ธธ๋๋ง๋ค Global, Script, Local ์๋ณ์๊ฐ ์๊ธฐ๋๋ฐ, Global, Script๋ ์ปจํ ์คํธ๋ง๋ค ๋์ผํ ๊ฒ์ ๋ฐ๋ผ๋ณด๊ณ Local ์๋ณ์๋ ์ปจํ ์คํธ๋ง๋ค ๋ค๋ฅธ ๊ฑด๊ฐ?
A. Scope์ ๋์์๋ Global, Script, Local์ ์๋ณ์๋ผ๊ธฐ ๋ณด๋จ, ์ปจํ ์คํธ๋ง๋ค ์ ๊ทผํ ์ ์๋ ์๋ณ์๋ค์ ํฌ๋กฌ ๋๋ฒ๊ฑฐ๊ฐ ์ค์ฝํ๋ณ๋ก ๋ชจ์๋์ ๋ถ๋ฅ๋ช ์ผ๋ก ๋ณด๋ ๊ฒ์ด ์ ์ ํ๋ค. ๋ฐ๋ผ์ ์ด๋ค ์ปจํ ์คํธ๊ฑด Global, Script๋ก ๋ถ๋ฅํด๋์ ์๋ณ์๋ ์ ์ญ ์ปจํ ์คํธ์ VO์์ ์๊ธฐ ๋๋ฌธ์ ๋์ผํ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ Global์ window๊ฐ์ฒด์ ํ๋กํผํฐ&๋ฉ์๋(var)๊ฐ ๋ค์ด๊ฐ์๊ณ , Script๋ ์คํฌ๋ฆฝํธ ์์์ ์์ฑํ ์๋ณ์(const, let)๊ฐ, Local์ ํด๋น ์ปจํ ์คํธ์์ ์์ฑ๋ ์๋ณ์๊ฐ ๋ค์ด๊ฐ๋ค.
ํจ์ ์ค์ฝํ
- ์๋ก์ด ํจ์๊ฐ ์์ฑ๋๋ฉด ์๋ก์ด ์ค์ฝํ๊ฐ ๋ฐ์ํ๋ค.
- ํจ์์์ ์ ์ธํ ๋ณ์๋ค์ ํด๋น ํจ์ ๋ด์์๋ง ์ ๊ทผํ ์ ์๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ๋ var ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ์ค๋ก์ง ํจ์ ์ฝ๋๋ธ๋ก๋ง์ ์ง์ญ ์ค์ฝํ๋ก ์ธ์ ํ๋ค.
if(5 > 4) {
var secret = '12345';
}
secret // '12345'
function a() {
var secret = '12345';
}
secret; //ReferenceError
aํจ์์ ๋ํ ์๋ก์ด ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋๊ณ , ์ด ์คํ ์ปจํ ์คํธ ๋ด๋ถ์ ์กด์ฌํ๋ ๋ณ์ํ๊ฒฝ(variable environment)์ secret๋ณ์๊ฐ ์ ์ฅ๋๋ค. ๋ฐ๋ผ์ ํจ์ ์ธ๋ถ์์ secret์ ์ ๊ทผํ๋ ค๊ณ ํ ๊ฒฝ์ฐ ์ค์ฝํ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ํด๋น ๋ณ์์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ๋ค. ํจ์์ธ๋ถ๋ global scope์ด๊ณ , ํจ์ ๋ด๋ถ๋ aํจ์์ scope์ธ๋ฐ ๋ถ๋ชจ์ค์ฝํ๋ ์์์ค์ฝํ์์ ๊ฐ์ญํ ์ ์๊ธฐ ๋๋ฌธ์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ๋ค.
๋ธ๋ก ์ค์ฝํ
- ๋ธ๋ก์ด ์์ฑ๋ ๋ ์๋ก์ด ์ค์ฝํ๊ฐ ์์ฑ๋๋ค.
- ํจ์๋ฟ๋ง์๋๋ผ, if๋ฌธ, for๋ฌธ...์์๋ ์ค์ฝํ๊ฐ ์์ฑ๋๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ๋ ์๋ ํจ์์ค์ฝํ๋ฅผ ๋ฐ๋ฅด์ง๋ง, let๊ณผ const์ ๋ฑ์ฅ์ดํ๋ก ๋ธ๋ก ์ค์ฝํ ํ์ฑ๋ ๊ฐ๋ฅํด์ก๋ค.
function loop() {
for (var j = 0; j < 3; j++) {
console.log(j);
}
console.log('final', j);
}
loop();
// 0
// 1
// 2
// final 3
function loop() {
for (let j = 0; j < 3; j++) {
console.log(j);
}
console.log('final', j);
}
loop();
// 0
// 1
// 2
// Uncaught ReferenceError: j is not defined
let์ผ๋ก ์ ์ธํ ๋ณ์๋ for๋ฌธ ๋ด(๋ธ๋ก ์ค์ฝํ)์์๋ง ์ข ์๋๋ฉฐ, for๋ฌธ ์ธ๋ถ์์๋ ์ ๊ทผํ ์ ์๋ค.
Lexical Scope
๋ ์์ปฌ ์ค์ฝํ๋ ํจ์์ ํธ์ถ ์์น์ ์๊ด ์์ด, ํจ์๊ฐ ์ด๋์ ์ ์ธ๋์๋์ง์ ๋ฐ๋ผ ์์ ์ค์ฝํ๋ฅผ ๊ฒฐ์ ํ๋ค. ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋ ๋, ์ค์ฝํ ์ฒด์ธ์ ์์ ์ค์ฝํ๋ฅผ ์ ์ฅํ ํ์ ์คํ๋๊ธฐ ๋๋ฌธ์ด๋ค.
๋ ์์ปฌ ์ค์ฝํ๋ ์ฝ๋๊ฐ ์ฐ์ฌ์ง ์๊ฐ ์ค์ฝํ๋ ์ด๋ฏธ ์ ํด์ง๊ธฐ ๋๋ฌธ์ ์ ์ ์ค์ฝํ๋ผ๊ณ ๋ ๋ถ๋ฆฐ๋ค.
์์ ์ฝ๋1)
var x = 1; // global
function first() {
var x = 10;
second();
}
function second() {
console.log(x);
}
first(); // ?
second(); // ?
๋ ์์ปฌ ์ค์ฝํ์์๋ ๋์ ์ค์ฝํ์ ํน์ง์ธ "ํจ์๋ฅผ ์ด๋์์ ํธ์ถํ์๋์ง"๋ ์ค์ฝํ ๊ฒฐ์ ๊ณผ ์ ํ ๋ฌด๊ดํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์, second() ํจ์๊ฐ first() ํจ์ ์์์ ํธ์ถ๋ ๊ฒ๊ณผ ์๊ด์์ด, second() ํจ์๋ ์ ์ญ ์ปจํ ์คํธ์์ ์ ์ธ๋์ด ์์ผ๋ฏ๋ก, ์ ์ญ ์ปจํ ์คํธ์ ๋ณ์ x์ ๊ฐ 1์ด ๋ ๋ฒ ์ถ๋ ฅ๋๋ค.
์์ ์ฝ๋2)
const x = 1
function outer() {
const x = 10
const inner = function() {
console.log(x)
}
return inner;
}
const junha = outer()
junha() // ?
innerํจ์๊ฐ ์ ์๋๋ ์์ ์ ์ค์ฝํ ์ฒด์ธ์ ์์ ์ค์ฝํ๋ outer ์ปจํ ์คํธ๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๊ธฐ ๋๋ฌธ์, x๋ outer์ x๋ฅผ ๋จผ์ ์ฐธ์กฐํด 10์ ์ถ๋ ฅํ๋ค. outer๊ฐ ์ฝ์คํ์์ ์ฌ๋ผ์ก์์๋ ๋ถ๊ตฌํ๊ณ , inner๊ฐ outer์ x๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ inner๋ ํด๋ก์ ์ด๋ค.
์์ ์ฝ๋3)
var c = 999
let arr = []
for(let i= 0 ; i<5 ; i++) {
let c = i * 2
arr.push(function inner() {console.log(c)})
}
arr.forEach(func => func())
// ?
ES6์์๋ ๋ธ๋ญ์ด ์์ฑ๋๋ฉด์๋ ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋๋ค. innerํจ์๊ฐ ์ ์๋๋ ์์ ์(= inner ์คํ์ปจํ ์คํธ๊ฐ ์์ฑ๋๋ ์์ ์) ์ด ๋ธ๋ญ์์ ์ ์ธ๋๊ธฐ ๋๋ฌธ์, inner์ ์คํ ์ปจํ ์คํธ์ ์ค์ฝํ์ฒด์ธ์ ๋ธ๋ก์ ์ฐธ์กฐํ๊ฒ ๋๋ค. ๋ฐ๋ผ์ innerํจ์๊ฐ ์ฐธ์กฐํ๋ c๋ ๋ธ๋ก์์ c๊ฐ ๊ฐ์ฅ ๋จผ์ ์ค์ฝํ์ด ๋๋ค.
๋ง์ฝ, ๋ธ๋ก์์ ์ง์ญ๋ณ์ c๊ฐ ์์๋ค๋ฉด?? innerํจ์์ ์ค์ฝํ ๋จ๊ณ๋ VO(inner) -> SC(๋ธ๋ก) -> SC(์ ์ญ)์ ํตํด ์ ์ญ๋ณ์ c๋ฅผ ์ฐธ์กฐํ์ฌ, 999๋ฅผ 5๋ฒ ์ถ๋ ฅํ๋ค.