๐ var, let, const ๋ณ์ ์ฐจ์ด์ ๊ณผ ํธ์ด์คํ (hoisting)
์ผ๋ฐ์ ์ผ๋ก var
, let
, const
๋ผ๊ณ ํ ๋์ ๊ธฐ๋ณธ์ ์ธ ์ฐจ์ด์ ์ ๋๋ต์ ์ผ๋ก๋๋ง ์๊ณ ์์ ๊ฒ์ด๋ค. (์ด๋ ดํ์ด ์์ฑํ ๋์ ๊ธ) ๊ฐ๋ตํ๊ฒ ๋งํ๋ฉด var
์ let
์ ๋ณ์๋ฅผ ์ ์ธํ๊ณ ๋ณ์๋ฅผ ํ ๋นํ ์ดํ์๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ง๋ง(์ ํํ๋ var
๋ ์ฌ์ ์ธ ๋ฐ ์ฌํ ๋น์ด ๊ฐ๋ฅํ๊ณ , let
์ ์ฌ์ ์ธ์ ๋ถ๊ฐ๋ฅํ์ง๋ง ์ฌํ ๋น์ ๊ฐ๋ฅํ๋ค.) const
๋ ํ๋ฒ ํ ๋นํ ๊ฐ์ ๋ค์ ๋ฐ๊ฟ ์ ์๋ค.
์ด๋ ๊ฒ var
๋ณ์์ ๋ฐ์ด๋ ์ ์ฐ์ฑ๋งํผ ๋จ์ ๋ ์๋๋ฐ,var
๋ฌธ๋ฒ์ ์ค์ฝํ์ ๋ฒ์(์ ํํ๊ฒ๋ ํจ์ ์ค์ฝํ)๊ฐ ๋์ด์ ์๋์น ์์ ๋ฒ๊ทธ์ ๋ฐ์์์ธ์ด ๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ES6
๋ฌธ๋ฒ์ let
, const
๋ฌธ๋ฒ์ด ์ถ๊ฐ๋๋ฉด์ var
๋์ let
, const
์ฌ์ฉ์ ๊ถ์ฅํ๊ณ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ณ์
์ ์ค์ฝํ
์ ๋ฒ์๋ ์ด๋ค ๊ด๊ณ๊ฐ ์์๊น? ์ด๋ฅผ ์๊ธฐ ์ํด์๋ JS
์ ๊ธฐ๋ณธ ํน์ฑ์ธ ํธ์ด์คํ
(hoisting)
์ ์์์ผ ํ๋๋ฐ, ํธ์ด์คํ
์ด๋ ๋ณ์ ๋ฐ ํจ์ ์ ์ธ์ด ๋ฌผ๋ฆฌ์ ์ผ๋ก ์์ฑํ ์ฝ๋์ ์๋จ์ผ๋ก ์ฎ๊ฒจ์ง๋ ๊ฒ์ด์ง๋ง, ์ค์ ๋ก๋ ๊ทธ๋ ์ง ์์ ๊ฒ์ ๋งํ๋ค. JS
์์๋ ํจ์ ์ ์ธ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๋ ๋ฐฉ์์ ์ฑํํ๋๋ฐ ์ด๊ฒ์ ์ฅ์ ์ ์ฝ๋์์ ์ ์ธํ๊ธฐ ์ ์ ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด๋ค. ๋ค์์ ์๋ฅผ ๋ณด์.
printMyname("์์์ฐ")
function printMyName(name){
console.log(`์ ์ด๋ฆ์ ${name}์
๋๋ค.`)
}
๐๐ฝ ์ ์ด๋ฆ์ ์์์ฐ์
๋๋ค.
์ด์ฒ๋ผ printMyName
ํจ์๋ฅผ ์ ์ธํ๊ธฐ ์ ์ธ๋ฐ๋ ๋ถ๊ตฌํ๊ณ printMyName
์ ํธ์ถํ๋ฉด ์ ์์ ์ผ๋ก ์ปดํ์ผํ๋ ๊ฒ์ ์ ์ ์๋ค. ๋ํ, ํธ์ด์คํ
์ ํจ์ ๋ด๋ถ์ ๊ตญํํ์ง ์๊ณ ํจ์ ์ธ๋ถ์์๋ ์ผ์ด๋๋๋ฐ, ์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ ๋ณ์ ์ ์ธ์ ํธ์ด์คํ
๋์ง๋ง, ๋ณ์ ํ ๋น์ ํธ์ด์คํ
์ด ์ผ์ด๋์ง ์๋๋ค. ๋ค์์ ์๋ฅผ ๋ณด์.
// ์ค์ ์ฝ๋
console.log(name); // undefined
var name = "์์์ฐ";
console.log(name); // ์์์ฐ
// ๋ด๋ถ ์๋ ์ฝ๋
var name; // isHoisting
console.log(name); // undefined
name = "์์์ฐ"; // assignment
console.log(name); // ์์์ฐ
๊ฐ์ ์ํฉ์์ let
์ ๋ค๋ฅด๊ฒ ์ถ๋ ฅ๋๋๋ฐ, ์ฝ๋๋ฅผ ์คํํ๋ฉด ReferenceError: Cannot access 'name' before initialization
์ค๋ฅ๊ฐ ๋ฌ๋ค.
console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name = "์์์ฐ";
console.log(name); // ์์์ฐ
๐ TDZ(Temporal Dead Zone), ์ค์ฝํ
var
๋ณ์์ ๋ฌ๋ฆฌ let
, const
๋ ํธ์ด์คํ
์ด ๋์ง ์์์ ์ด๋ฐ ์๋ฌ๊ฐ ๋จ๋ ๊ฒ์ผ๊น? ๊ทธ๋ ์ง ์๋ค. let
, const
๋ณ์๋ ํธ์ด์คํ
๋๋ค. ํ์ง๋ง var
๋ณ์์๋ ๋ค๋ฅด๊ฒ let
, const
๋ณ์๋ TDZ(Temporal Dead Zone)
์ ์ํฅ์ ๋ฐ๋๋ค. ์ด์ ์ฝ๋์์ TDZ
์ ์์ญ์ ๋ค์๊ณผ ๊ฐ๋ค. TDZ(Temporal Dead Zone)
๋ ์๊ฐ์ ์ฌ๊ฐ์ง๋๋ฅผ ์๋ฏธํ๋๋ฐ, ๋ณ์๊ฐ ๋ธ๋ก ์์๋ถํฐ ์ด๊ธฐํ๊ฐ ์๋ฃ๋ ๋๊น์ง๋ฅผ TDZ
๋ผ๊ณ ์ผ์ปซ๋๋ค. ์ฝ๊ฒ ๋งํด์ ๋ณ์์ ์ค์ง์ ์ธ ๊ฐ์ ํ ๋นํ๊ธฐ ์ ์ ์ฌ์ฉํ ์ ์๋๋ฐ TDZ
๋ฅผ ์ค์ ํ๋ ์ด์ ๋ ์ฝ๋๋ฅผ ์์ธก ๊ฐ๋ฅํ๊ณ , ์ ์ฌ์ ์ธ ๋ฒ๊ทธ๋ฅผ ์ค์ด๊ธฐ ์ํจ์ด๋ค.
console.log(name); // TDZ(Temporal Dead Zone)
let name = "์์์ฐ";
console.log(name); // ์์์ฐ
JS
์์ ๋ณ์์ ์์ฑ๊ณผ์ ์ 3๋จ๊ณ์ ๊ฑธ์ณ์ ์ ์๋๋๋ฐ, ๋ณ์ ์ ์ธ → ๋ณ์ ์ด๊ธฐํ → ๋ณ์ ํ ๋น์ ์์๋ก ์ ์๋๋ค. ์ฌ๊ธฐ์ var
let
, const
๋ ๊ฐ๊ฐ ๋ค๋ฅธ ๊ณผ์ ์ผ๋ก ๋ณ์๊ฐ ๋ง๋ค์ด์ง๋ค.
์ฐ์ , var
๋ ์ ์ธ ๋จ๊ณ + ์ด๊ธฐํ ๋จ๊ณ๊ฐ ๋์์ ์ด๋ฃจ์ด์ง๊ณ ์ดํ ํ ๋น ๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ค. ๋ค์์ ์ฝ๋๋ฅผ ๋ณด์. ์ ์ธํ์ง๋ ์์ name
๊ฐ์ undefined
๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ์ ์ ์๋๋ฐ, ์ด๋ ํธ์ด ์คํ
๊ณผ์ ์ ๊ฑฐ์น๋ฉด์ var
๋ณ์์ ์์ฑ + var
์ด๊ธฐํ ๊ฐ undefined
์ด ๋์์ ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์ด๋ค. ์ดํ name = "์์์ฐ"
๋ผ๋ ๊ฐ์ ํ ๋นํ๋ฉด ๊ทธ์ ์ผ ๋ด๊ฐ ํ ๋นํ ๊ฐ์ธ ์์์ฐ
๊ฐ์ด ๋์จ๋ค.
// ์ค์ ์ฝ๋
console.log(name); // undefined
var name;
name = "์์์ฐ";
console.log(name); // ์์์ฐ
// ๋ด๋ถ ํธ์ด์คํ
var name;
console.log(name); // undefined
name = "์์์ฐ";
console.log(name); // ์์์ฐ
๋ค์์ผ๋ก let
์ ์ ์ธ → ์ด๊ธฐํ → ํ ๋น ์์ผ๋ก ์ด๋ฃจ์ด์ง๋๋ฐ, ๋ค์์ ์ฝ๋์์๋ let
์ด ํธ์ด์คํ
๋๋ฉด์ ์ ์ธ ๋จ๊ณ๊น์ง ์ด๋ฃจ์ด์ก์ง๋ง, ๋ณดํต ์ด๊ธฐํ ๋จ๊ณ๋ ์ค์ ์ฝ๋์ ๋๋ฌํ์ ๋ ์ผ์ด๋๊ธฐ ๋๋ฌธ์ ReferenceError
๊ฐ ๋์ค๋ ๊ฒ์ด๋ค.
// ์ค์ ์ฝ๋
console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name;
name = "์์์ฐ";
console.log(name); // ์์์ฐ
// ๋ด๋ถ ํธ์ด์คํ
console.log(name); // TDZ
let name;
name = "์์์ฐ";
console.log(name); // ์์์ฐ
๋ง์ง๋ง์ผ๋ก const
๋ ์ ์ธ + ์ด๊ธฐํ + ํ ๋น ๋ชจ๋ ๋์์ ์ด๋ฃจ์ด์ ธ์ผ ํ๋ค. var
, let
๋ ์ ์ธ๋ง ํด๋๊ณ ๋์ค์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ๋ฅํ์ง๋ง const
๋ ํ ๋ฒ์ ํ ๋น๊น์ง ํด์ผ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
// var
var name;
name = "์์์ฐ";
// let
let age;
age = 27;
// const
const gender;
gender = "male"; // SyntaxError: Missing initializer in const declaration
๋, var
, let
, const
๋ณ์๋ ํธ์ถ ๊ฐ๋ฅํ ์์ญ(?)์ธ ์ค์ฝํ๊ฐ ๊ฐ๊ฐ ์ ํด์ ธ ์๋๋ฐ ์ฌ๊ธฐ์ ์ค์ฝํ๋ ํ์ฌ ์คํ๋๋ ์ปจํ
์คํธ(context)
์ฝ๊ฒ ๋งํด ๋ณ์ ๋๋ ๋ค๋ฅธ ํํ์์ด ํด๋น ์ค์ฝํ๋ด์ ์์ง ์๋ค๋ฉด ์ฌ์ฉํ ์ ์๋ค. ์ค์ฝํ๋ ๋ํ ๊ณ์ธต์ ์ธ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ํ์ ์ค์ฝํ๋ ์์ ์ค์ฝํ์ ์ ๊ทผํ ์ ์์ง๋ง ๋ฐ๋๋ ๋ถ๊ฐํ๋ค.
var
๋ ํจ์ ์ค์ฝํ(function-scoped)
์ ์ํฅ์, let
, const
๋ ๋ธ๋ก ์ค์ฝํ(block-scoped)
์ ์ํฅ์ ๋ฐ๋๋ค.
var
๋ณ์๋ ์ ์ผํ๊ฒ ํจ์ ์ค์ฝํ(function-scoped)
์ํฅ์ ๋ฐ๋๋ค๊ณ ํ๋๋ฐ, ์ฝ๊ฒ ๋งํ๋ฉด ํจ์ ๋ด๋ถ์์ ๊ฐ์ ํธ์ถํ ๋๋ ํจ์์ธ๋ถ์์ ํธ์ถ ํ ์ ์๊ณ ํจ์ ๋ด๋ถ์์๋ง ํธ์ถ ํ ์ ์๊ณ ๋ค๋ฅธ ์กฐ๊ฑด๋ฌธ, ๋ฐ๋ณต๋ฌธ ๋ฑ์์๋ ํธ์ถ์ด ๊ฐ๋ฅํ๋ค. ๋ค์ ์๋ฅผ ๋ณด์.
// ํจ์ score ์ธ๋ถ์์ var๋ณ์ ํธ์ถ(๋ถ๊ฐ๋ฅ)
function myName(){
var name = "์์์ฐ";
}
myName();
console.log(name); // ReferenceError: name is not defined
// ํจ์ score ๋ด๋ถ์์ var๋ณ์ ํธ์ถ(๊ฐ๋ฅ)
function myName(){
var name = "์์์ฐ";
console.log(name);
}
myName(); // ์์์ฐ
// ์กฐ๊ฑด๋ฌธ ๋ฐ์์ var๋ณ์ ํธ์ถ(๊ฐ๋ฅ)
if (true){
var age = 27;
}
console.log(age); // 27
let
, const
๋ ๋ธ๋ก ์ค์ฝํ์ ์ํฅ์ ๋ฐ๋๋ค. ์ฌ๊ธฐ์ ๋ธ๋ก์ด๋ ์ค๊ดํธ ๋ด๋ถ (if
, for
, while
, try/catch
๋ฌธ ๋ฑ)์ ๋ปํ๋ค.
// if๋ฌธ ๋ด๋ถ์์ ํธ์ถ(๊ฐ๋ฅ)
if(true){
let age = 27;
console.log(age); // 27
}
// if๋ฌธ ์ธ๋ถ์์ ํธ์ถ(๋ถ๊ฐ๋ฅ)
if(true){
let age = 27;
}
console.log(age); // ReferenceError: age is not defined
// function ๋ด๋ถ์์ ํธ์ถ(๊ฐ๋ฅ)
function showMyAge(){
const age = 27;
console.log(age);
}
showMyAge(); // 27
// function ์ธ๋ถ์์ ํธ์ถ(๋ถ๊ฐ๋ฅ)
function showMyAge(){
const age = 27;
}
showMyAge();
console.log(age); // ReferenceError: age is not defined
์ง๊ธ๊น์ง var
, let
,const
๋ณ์๋ค์ ์ฐจ์ด์ ๊ณผ ํธ์ด์คํ
(hoisting), TDZ, ์ค์ฝํ์ ๋ํด์ ๋ฐฐ์ ๋ค. var
๋ ์ด์ ์ฌ์ฉํ์ง ์๊ณ , let
,const
๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ์์ธก ๊ฐ๋ฅํ๊ณ ์ ์ฌ์ ์ธ bug
๋ฅผ ์ค์ด๊ธฐ ์ํ ๊ฒ์์ ๊ธฐ์ตํ์.
- Reference
๋๊ธ