๐ ๋ค์ด๊ฐ๋ฉฐ
์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฝ๋์ ์คํ ์์์ ์ค์ฝํ๋ฅผ ์ดํดํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํ๋ ์ค์ํ ๊ฐ๋ ์ค ํ๋์ธ ํธ์ด์คํ (hoisting)์ ๋ํด์ ์์๋ณด๊ฒ ์ต๋๋ค.
ํธ์ด์คํ (hoisting)์ด๋ โ
ํธ์ด์คํ ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์คํฌ๋ฆฝํธ๋ฅผ ํด์ํ๊ณ ์คํํ๋ ๊ณผ์ ์์, ๋ณ์๋ ํจ์, ํด๋์ค ์ ์ธ์ ์ฝ๋์ ๋งจ ์๋ก '๋์ด์ฌ๋ฆฌ๋' ๊ฒ๊ณผ ๊ฐ์ ํ์์ ๋งํฉ๋๋ค.
๋ณดํต ํธ์ด์คํ ์ ๋ํ ์ค๋ช ์ ๋ณด๋ฉด '๋์ด์ฌ๋ ค์ง๋ค'๋ผ๊ณ ๋๋ถ๋ถ ์ค๋ช ์ด ๋์ด ์๋๋ฐ ํธ์ด์คํ ์ด ์ค์ ๋ก ์ฝ๋๋ฅผ ๋ฌผ๋ฆฌ์ ์ผ๋ก ์ต์๋จ์ผ๋ก ์ฎ๊ธฐ๋ ๊ฒ์ ์๋๋๋ค.
์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๋ด๋ถ ๋์ ๋ฐฉ์์ ์ค๋ช ํ๋ ๊ฐ๋ ์ผ ๋ฟ์ ๋๋ค.
ํธ์ด์คํ ์ ์คํ ์ปจํ ์คํธ์ ์์ฑ ๋จ๊ณ์์ ์ผ์ด๋ฉ๋๋ค.
์คํ ์ปจํ ์คํธ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๊ฐ ์คํ๋๋ ํ๊ฒฝ์ ๋งํฉ๋๋ค.
์์ฑ ๋จ๊ณ์์๋ ๋ณ์ ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ง๊ณ , ์ค์ฝํ ์ฒด์ธ์ด ํ์ฑ๋๋ฉฐ, this ๊ฐ์ด ๊ฒฐ์ ๋ฉ๋๋ค.
๋ณ์ ๊ฐ์ฒด ๋ด๋ถ์๋ ์ธ์, ๋ด๋ถ ๋ณ์, ๋ด๋ถ ํจ์ ๋ฑ์ด ํฌํจ๋์ด ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ณ์
์๋ฐ์คํฌ๋ฆฝํธ์์ ๋ณ์๋ var, let, const ํค์๋๋ฅผ ์ฌ์ฉํด ์ ์ธํ ์ ์์ต๋๋ค.
๋ณ์ ์์ฑ ๋จ๊ณ
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์คํ ์ปจํ ์คํธ Lexical Environment์ ๋ณ์๋ฅผ ๋ฑ๋กํ๋ ๊ณผ์ ์์ ์ด 3๊ฐ์ง ๋จ๊ณ๊ฐ ์์ต๋๋ค.
1. ์ ์ธ(Declaration) ๋จ๊ณ
ํน์ ์ด๋ฆ์ ๋ณ์๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ ๋๋ค.
์ด ๋จ๊ณ์์๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ณ์๋ฅผ ์ํ ๊ณต๊ฐ์ด ํ๋ณด๋๋ฉฐ, ์ด ๊ณต๊ฐ์ ๋ณ์ ์ด๋ฆ์ผ๋ก ์ฐธ์กฐ๋ ์ ์๊ฒ ๋ฉ๋๋ค.
2. ์ด๊ธฐํ(Initalization) ๋จ๊ณ
์ ์ธ๋ ๋ณ์์ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ๋ ๋จ๊ณ์ ๋๋ค.
ํด๋น ๋จ๊ณ์์ ๋ณ์๋ undefined๋ก ์ด๊ธฐํ๊ฐ ๋ฉ๋๋ค.
๋์ , var๋ก ์ ์ธ๋ ๋ณ์๋ ์ ์ธ๊ณผ ๋์์ undefined๋ก ์ด๊ธฐํ๊ฐ ๋ฉ๋๋ค. ์ฆ, ์ค์ฝํ์ ๋ณ์๋ฅผ ๋ฑ๋ก(์ ์ธ ๋จ๊ณ)ํ๊ณ ๋ฉ๋ชจ๋ฆฌ์ ๋ณ์๋ฅผ ์ํ ๊ณต๊ฐ์ ํ๋ณดํ ํ undefined๋ก ์ด๊ธฐํํฉ๋๋ค.
๋ฐ๋ฉด์, let๊ณผ const๋ก ์ ์ธ๋ ๋ณ์๋ ์ค์ฝํ์ ๋ณ์๋ฅผ ๋ฑ๋ก(์ ์ธ ๋จ๊ณ)ํ์ง๋ง ์ด๊ธฐํ ๋จ๊ณ๋ ๋ณ์ ์ ์ธ๋ฌธ์ ๋๋ฌํ์ ๋(์ฝ๋ ์คํ ํ) ์ด๋ค์ง๋๋ค.
console.log(name); // (์ ์ธ + ์ด๊ธฐํ ๋ ์ํ)
name = 'yong'; // (์ ์ธ + ์ด๊ธฐํ + ํ ๋น ๋ ์ํ)
var name;
console.log(name);
// ํธ์ด์คํ
๋ฐ์ํจ
console.log(text); // TDZ(Temporal Dead Zone)์ ์์ด์ ์ฐธ์กฐ ์๋ฌ ๋ฐ์
let text; // ์ ์ธ๋ฌธ์ ๋๋ฌํ์ฌ ์ด๊ธฐํ ๋จ๊ณ ์คํ
3. ํ ๋น(Assignment) ๋จ๊ณ
์ด๊ธฐํ๋ ๋ณ์์ ํน์ ๊ฐ์ ์ง์ ํ๋ ๋จ๊ณ์ ๋๋ค.
var ํธ์ด์คํ
var๋ก ์ ์ธ๋ ๋ณ์๋ ํจ์ ์ค์ฝํ์์ ํธ์ด์คํ ๋ฉ๋๋ค.
์ฆ, ํจ์ ๋ด๋ถ ์ด๋์์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ฉฐ, ์ ์ธ ์ ์ ์ฌ์ฉํด๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๊ณ undefined๊ฐ ์ถ๋ ฅ๋๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
console.log(name); // 'undefined'
var name = 'yong';
var ํค์๋์ ํน์ง์ var ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ํธ์ด์คํ ์ ์ํด ๋งจ ์๋ก ๋์ด์ฌ๋ ค์ง ๋ ์๋์ผ๋ก undefined ๊ฐ์ผ๋ก ์ด๊ธฐํ๊ฐ ๋ฉ๋๋ค.
๊ทธ๋์ ์ ์ธ๋ฌธ ์ ์ ์ ๊ทผ์ ํ ์ ์๋ ์ํฉ์ด ๋ฐ์ํ ๊ฒ์ ๋๋ค.
ํธ์ด์คํ ์ ๋์ ๊ณผ์ ์ ์๋ฅผ ๋ค๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
name;
console.log(name);
name = 'yong';
let, const ํธ์ด์คํ
let๊ณผ const๋ก ์ ์ธ๋ ๋ณ์๋ ํธ์ด์คํ ์ด ๋๋๋ฐ, ๋ธ๋ก ์ค์ฝํ์์ ํธ์ด์คํ ์ด ๋ฉ๋๋ค.
ํ์ง๋ง, var ํค์๋์๋ ๋ค๋ฅด๊ฒ ์ ์ธ ์ ์ ์ ๊ทผํ๋ ค ํ๋ฉด ์ฐธ์กฐ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋๋ฐ ์ด๋ฅผ 'TDZ - Temporal Dead Zone (์ผ์์ ์ฌ๊ฐ์ง๋)'๋ผ๊ณ ํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ TDZ์ ๋ค์ด๊ฐ ์๋ ๊ฒ๋ค์ ์ ๊ทผ์ ํ์ฉํ์ง ์์ต๋๋ค.
console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name = 'yong';
console.log(age); // ReferenceError: Cannot access 'age' before initialization
const age = 25;
let foo = 1;
{
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
let foo = 2;
// ๋ธ๋ก ์ค์ฝํ ์์์ ํธ์ด์คํ
์ด ์ผ์ด๋๊ธฐ ๋๋ฌธ์ ์ฐธ์กฐ ์๋ฌ ๋ฐ์
}
๊ทธ๋ฆฌ๊ณ let์ var์ ๊ฐ์ด ์ฌ์ ์ธ์ด ํ์ฉ์ด ๋์ง๋ง,
const๋ ์ฌ์ ์ธ์ด ํ์ฉ๋์ง ์๊ธฐ ๋๋ฌธ์ const ํค์๋๋ฅผ ์ฌ์ฉ ์ ์ ์ธ๊ณผ ๋์์ ํ ๋น์ ํด์ฃผ์ด์ผ ํฉ๋๋ค.
// โ
let num = 0;
console.log(num) // 0
num = 15;
---------------
// โ
const name; // SyntaxError: Missing initializer in const declaration
console.log(name)
---------------
// โ
const age = 15;
console.log(age) // 15
var, let, const ์ ๋ฆฌ
var ํค์๋๋ ํจ์ ์ค์ฝํ๋ฅผ ๊ฐ์ง๊ณ ํธ์ด์คํ ์ undefined๋ก ์ด๊ธฐํ๋๊ณ ๊ฐ์ ์ค์ฝํ ๋ด์์ ์ฌ์ ์ธ์ด ๊ฐ๋ฅํ ๋ฐฉ์ ๋ฑ ๋ ํนํ ๋ฐฉ์ ๋๋ฌธ์ ํผ๋์ ์ด๋ํ ์ ์์ต๋๋ค.
๋ฐ๋ฉด์, let๊ณผ const๋ ๋ธ๋ก ์ค์ฝํ๋ฅผ ๊ฐ์ง๋ฏ๋ก, ์ฝ๋๊ฐ ๋ ์์ธก์ด ๊ฐ๋ฅํ๊ณ ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค.
๋ฐ๋ผ์, ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์๋ var ๋์ ์ let๊ณผ const๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋๊ณ ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ํจ์ ์ ์ธ
ํจ์์ ์ ์ธ ๋ฐฉ์์๋ ์ ์ธ์๊ณผ ํํ์์ด ์์ต๋๋ค.
ํจ์ ์ ์ธ์๊ณผ ํธ์ด์คํ
ํจ์ ์ ์ธ์๋ ํธ์ด์คํ ์ ๋์์ด๋ฉฐ ํจ์ ์ ์ฒด๊ฐ ํธ์ด์คํ ์ด ๋ฉ๋๋ค.
console.log(myFunction()); // "Hello, World!"
function myFunction() {
return "Hello, World!";
}
ํจ์ ํํ์๊ณผ ํธ์ด์คํ
ํจ์ ํํ์์ ๋ณ์์ ํ ๋น๋ ํจ์๋ฅผ ์๋ฏธํ๋ฉฐ, ๋ณ์ ์ ์ธ๋ง ํธ์ด์คํ ์ด ๋๊ณ ํจ์๋ ํธ์ด์คํ ์ด ๋์ง ์์ต๋๋ค.
์ฆ, ํจ์ ํํ์์ ์ ์ธ ์ ์ ํธ์ถํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
console.log(myFunctionExpression()); // TypeError: myFunctionExpression is not a function
var myFunctionExpression = function() {
return "Hello, World!";
};
์๋ฌ๊ฐ ๋ฐ์ํ๋ ์ด์ ์ ํธ์ด์คํ ์ ๊ณผ์ ์ ์๋์ ๊ฐ์ต๋๋ค.
myFunctionExpression;
console.log(myFunctionExpression()); // TypeError: myFunctionExpression is not a function
myFunctionExpression = function() {
return "Hello, World!";
};
ํด๋์ค์ ํธ์ด์คํ
ํด๋์ค์ ์ ์ธ๋ ํธ์ด์คํ
์ ๋์์ด์ง๋ง, let๊ณผ const์ ๋ง์ฐฌ๊ฐ์ง๋ก ํธ์ด์คํ
์ด ์ผ์ด๋๋ 'TDZ'์ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ํด๋์ค ์ ์ธ ์ด์ ์ ํด๋น ํด๋์ค๋ฅผ ์ฐธ์กฐํ๋ ค๊ณ ํ๋ฉด ์ฐธ์กฐ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
const toy = new Toy(); // ReferenceError: Cannot access 'Toy' before initialization
class Toy {}
๐ ๋ง๋ฌด๋ฆฌ
ํธ์ด์คํ ์ ์ดํดํ๋ฉด ์ฝ๋๋ฅผ ๋ณด๋ค ํจ๊ณผ์ ์ผ๋ก ์์ฑํ๊ณ ๋๋ฒ๊น ํ ์ ์์ต๋๋ค.
์ฐธ๊ณ ๋ฌธํ: