Chapter 5: The (Not So) Secret Lifecycle of Variables - hochan222/Everything-in-JavaScript GitHub Wiki
When Can I Use a Variable?
greeting();
// Hello!
function greeting() {
console.log("Hello!");
}
์ ์ธ์ ๋ฐ์ํ๋๋ฐ greeting()์ ์ ์คํ๋ ๊น...?
1์ฅ์์ ์ฐ๋ฆฌ๋ ๋ชจ๋ ์๋ณ์๊ฐ ์ปดํ์ผ ์๊ฐ๋์ ํด๋น ๋ฒ์์ ๋ฑ๋ก๋๋ค๋ ์ ์ ๋ฐฐ์ ๋ค. ๋ํ, ๋ชจ๋ ์๋ณ์๋ ํด๋น ๋ฒ์๊ฐ ์
๋ ฅ ๋ ๋๋ง๋ค ํด๋น ๋ฒ์์ ์์ ๋ถ๋ถ์ ์์ฑ๋๋ค. ์ด๋ฅผ ํธ์ด์คํ
(hoisting)์ด๋ผ๊ณ ํ๋ค.
ํ์ง๋ง ํธ์ด์คํ
๋ง์ผ๋ก๋ ์ง๋ฌธ์ ๋ํ ๋ต์ ์ฐพ์ ์ ์๋ค. ์ค์ฝํ์ ์์ ๋ถ๋ถ์์ greeting์ด๋ผ๋ ์๋ณ์๋ฅผ ๋ณผ ์ ์์ง๋ง, ์ ์ธ๋๊ธฐ ์ ์ greeting() ํจ์๋ฅผ ํธ์ถ ํ ์์๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ?
์ด ๋ง์ ๋ค์๊ณผ ๋์ผํ๋ค.
์ค์ฝํ๊ฐ ์คํ๋๊ธฐ ์์ํ๋ ์๊ฐ๋ถํฐ greeting ๋ณ์์ ๊ฐ(function reference)์ด ํ ๋น๋๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ธ๊ฐ?
๋ต์ ํจ์ ํธ์ด์คํ ์ด๋ผ๊ณ ํ๋ ๊ณต์ ํจ์ ์ ์ธ์ ํน์ํ ํน์ฑ๋๋ฌธ์ด๋ค. ํจ์ ์ ์ธ์ ์ด๋ฆ ์๋ณ์๊ฐ ๋ฒ์์ ๋งจ ์์ ๋ฑ๋ก๋๋ฉด ํด๋น ํจ์์ ์ฐธ์กฐ์ ๋ํด ์ถ๊ฐ๋ก ์๋ โโ์ด๊ธฐํ๋๋ค.
Hoisting: Declaration vs. Expression
greeting();
// TypeError
var greeting = function greeting() {
console.log("Hello!");
};
ํธ์ด์คํธ๋๋ ๊ฒ ์ธ์๋ var๋ก ์ ์ธ ๋ ๋ณ์๋ ๋ฒ์์ ์์ ๋ถ๋ถ์์ ์๋์ผ๋ก undefined๋ก ์ด๊ธฐํ๋๋ค. ๋ฐ๋ผ์, greeting์ ๋ฐ์์ ํจ์๋ก ์ ์ธ๋๊ธฐ์ ๊น์ง๋ ํจ์ ์ฐธ์กฐ๋ก ์ฐ๊ฒฐ์ด ์๋๋ค.
Variable Hoisting
greeting = "Hello!";
console.log(greeting);
// Hello!
var greeting = "Howdy!";
- ์๋ณ์๊ฐ ์ฌ๋ผ์จ๋ค.
- undefined๋ก ์ด๊ธฐํ๋๋ค.
- ์ฝ๋๋ฅผ ์งํํ๋ค.
Hoisting: Yet Another Metaphor
JS์์ง์ ์คํ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ด ์ถ์ธก ํ ์ ์๋ค.
var greeting; // hoisted declaration
greeting = "Hello!"; // the original line 1
console.log(greeting); // Hello!
greeting = "Howdy!"; // `var` is gone!
ํ๊ฐ์ง ์์๋ฅผ ๋ ๋ณด์.
studentName = "Suzy";
greeting();
// Hello Suzy!
function greeting() {
console.log(`Hello ${ studentName }!`);
}
var studentName;
์ ๊ฐ์ ์ฝ๋๋ ์๋์ ๊ฐ์ด JS์์ง์ ์ํด ๋ณํ ๋ ๊ฒ์ด๋ค.
function greeting() {
console.log(`Hello ${ studentName }!`);
}
var studentName;
studentName = "Suzy";
greeting();
// Hello Suzy!
ํธ์ด์คํ ์ ๋ฒ์๊ฐ ์ ๋ ฅ ๋ ๋๋ง๋ค ๋ณ์์ ์๋ ๋ฑ๋ก์ ์ํด ์ปดํ์ผ ์์ ์ค์ ๋ฐํ์ ๋ช ๋ น์ ์์ฑํ๋ ์์ ์ผ๋ก ์๊ฐํ์.
Re-declaration?
var studentName = "Frank";
console.log(studentName);
// Frank
var studentName;
console.log(studentName);
// ???
๋ณ์๊ฐ ๋๋ฒ ์ ์ธ๋๋ฉด ์ด๋ป๊ฒ ๋์ํ ๊น...? ํธ์ด์คํ ๊ด์ ์์ ์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์งํ๋๋ค.
var studentName;
var studentName; // clearly a pointless no-op!
studentName = "Frank";
console.log(studentName);
// Frank
console.log(studentName);
// Frank
๋ฐ๋ผ์ ๋๋ฒ์งธ var studentName;
๋ ๋ฌด์๋ฏธํ๋ค.
(2์ฅ์ ๋น๋ฆฌ๋ฉด, ์ค์ฝํ ๊ด๋ฆฌ์์๊ฒ studentName ์ ์ธ์ด ๋์๋์ง ๋ฌป๊ธฐ ๋๋ฌธ์ ์๋ฌด ์์
๋ ํ์ง ์๋๋ค)
let studentName = "Frank";
console.log(studentName);
let studentName = "Suzy";
let์ ์ฌ์ ์ธ์ ํ์ฉํ์ง ์๋๋ค. SyntaxError.
ES6๊ฐ let์ ๋์
ํ์ ๋ โ์ฌ ์ ์ธโ์ ๋ฐฉ์งํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ค.
Constants?
const ํค์๋๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ณ์๋ฅผ ์ด๊ธฐํํด์ผํ๋ฏ๋ก ์ ์ธ์์ ํ ๋น์ ์๋ตํ๋ฉด SyntaxError๊ฐ ๋ฐ์ํ๋ค.
const empty; // SyntaxError
const studentName = "Frank";
console.log(studentName);
// Frank
studentName = "Suzy"; // TypeError
SyntaxError๋ ํ๋ก๊ทธ๋จ ์คํ ์ ์ ๋ฐ์ํ๋ ์ค๋ฅ์ด๊ณ TypeError๋ ํ๋ก๊ทธ๋จ ์คํ์ค์ ๋ฐ์ํ๋ ์๋ฌ์ด๋ค. ๋ฐ๋ผ์ const์์ TypeError๋ ์ปดํ์ผ ์ค์ ๋ฐ์ํ์ง ์๋๋ค.
์ฌ์ ์ธ๋ ์๋๋ค.
const studentName = "Frank";
// obviously this must be an error
const studentName = "Suzy";
Loops
for (const i = 0; i < 3; i++) {
// oops, this is going to fail with
// a Type Error after the first iteration
}
Uninitialized Variables (aka, TDZ)
console.log(studentName);
// ReferenceError
let studentName = "Suzy";
studentName = "Suzy"; // let's try to initialize it!
// ReferenceError
console.log(studentName);
let studentName;
var๋ก๋ ์๋๋๋ฐ let์ ReferenceError๊ฐ ๋๋ค.
let studentName = "Suzy";
console.log(studentName);
// Suzy
var๋ฅผ ์ฌ์ฉํ๋ฉด studentName์ด ๋งจ์์์ ์๋ ์ด๊ธฐํ๊ฐ ๋๋๋ฐ let๊ณผ const๋ ๊ทธ๋ ์ง ๋ชปํ๋ค.
์ค์ฝํ ์ ๋ ฅ๋ถํฐ ๋ณ์ ์๋ ์ด๊ธฐํ๊ฐ ๋ฐ์ํ๋ ๊ธฐ๊ฐ์ ์ง์นญํ๊ธฐ ์ํด TC39์์ ๋ง๋ ์ฉ์ด๋ TDZ (Temporal Dead Zone)์ด๋ค. TDZ๋ ๋ณ์๊ฐ ์กด์ฌํ์ง๋ง ์ฌ์ ํ ์ด๊ธฐํ๋์ง ์์๊ธฐ ๋๋ฌธ์ ์ด๋ค ๋ฐฉ์์ผ๋ก๋ ์ก์ธ์ค ํ ์ ์๋ ๊ฒ์ด๋ค.
var์ ๊ธฐ์ ์ ์ผ๋ก TDZ๊ฐ ์์ง๋ง ๊ธธ์ด๊ฐ 0์ด๋ฏ๋ก ํ๋ก๊ทธ๋จ์์ ๊ด์ฐฐ ํ ์ ์๋ค. let๊ณผ const์๋ง ๊ด์ฐฐ ๊ฐ๋ฅํ TDZ๊ฐ ์๋ค.
askQuestion();
// ReferenceError
let studentName = "Suzy";
function askQuestion() {
console.log(`${ studentName }, do you know?`);
}
์ค์ ๋ก๋ let๊ณผ const๊ฐ ํธ์ด์คํ
์๋๋๊ฒ์๋๊ณ ๋์ง๋ง ์ด๊ธฐํ๊ฐ ์๋๋๊ฒ์ด๋ค.
๋
ผ์์ ์ฌ์ง๋ ์๋ ์ด๊ธฐํ๊ฐ ํธ์ด์คํ
์ ์ผ๋ถ์ธ์ง ์ฌ๋ถ์ด๋ค.
var studentName = "Kyle"; {
console.log(studentName);
// ???
// ..
let studentName = "Suzy";
console.log(studentName);
// Suzy
}
๋ค์ ์ฝ๋๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํจ๋ค. ๋ง์ฝ ํธ์ด์คํ ์ด ์๋๋ค๋ฉด ์ฒซ๋ฒ์งธ console์์ Kyle์ด ์ถ๋ ค๋ผ์ผํ๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ํธ์ด์คํ ์ด ๋ฐ์ํจ์ ์ ์ ์๋ค. ์ด๊ธฐํ๋ง ์๋์ ๋ฟ์ด๋ค.