๐ง 01. ์คํ ์ปจํ ์คํธ & ์ค์ฝํ โ JS ์์ง์ ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ์ฝ๋๊ฐ?
๐ ๊ฐ์
JS ์์ง์ด ์ฝ๋๋ฅผ ์คํํ๋ ๋ฐฉ์, ํธ์ด์คํ ์ ์๋ฆฌ, var/let/const ์ค์ฝํ์ ์ฐจ์ด๋ฅผ ์ค๋ฌด ๊ด์ ์์ ์์ ์ ๋ณตํฉ๋๋ค.
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
- JS ์์ง์ด ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ ์ ๋ฌด์์ ๋จผ์ ํ๋์ง ์ค๋ช ํ ์ ์๋ค.
- ํธ์ด์คํ (Hoisting)์ด ์ ์ผ์ด๋๋์ง,
var๊ฐ ์ ๋ ๊ฑฐ์ ๋์๊ฐ ๋๋์ง ์ดํดํ๋ค.- ์ค์ฝํ ์ฒด์ธ(Scope Chain)์ด ๋ณ์ ํ์์ ์ด๋ป๊ฒ ํ๋์ง ๋จธ๋ฆฟ์์ ๊ทธ๋ฆด ์ ์๋ค.
๐ ๋ชฉ์ฐจ
- ๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
- ๐ค 1. ์ ์์์ผ ํ๋๊ฐ?
- ๐๏ธ 2. ์คํ ์ปจํ ์คํธ๋?
- ๐ 3. ํธ์ด์คํ โ ์ ์ธ์ด ์๋ก ๋๋ ค์ฌ๋ผ๊ฐ๋ค?
- ๐๏ธ 4. ์ค์ฝํ & ์ค์ฝํ ์ฒด์ธ
- ๐ 5. ์ค๋ฌด ํจํด ์ ๋ฆฌ
- ๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
- ๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
- ๐ ๋ ์์๋ณด๊ธฐ
๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 20๋ถ(์ ์ฒด) / ํต์ฌ ํํธ๋ง: 12๋ถ
๐บ๏ธ ์ด ๋ฌธ์์ ํ๋ฆ
[JS ์์ง์ 2๋จ๊ณ ์คํ] โ [์คํ ์ปจํ
์คํธ ์์ฑ] โ [ํธ์ด์คํ
์ดํด] โ [์ค์ฝํ ์ฒด์ธ ํ์]
๐ฏ ์ด ๋ฌธ์๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- "์
var๋ฅผ ์ฐ์ง ๋ง๋ผ๋ ๊ฑฐ์ผ?"์ ๊ธฐ์ ์ ๊ทผ๊ฑฐ๋ก ๋ตํ ์ ์๋ค. -
ReferenceError: Cannot access before initialization์๋ฌ์ ์์ธ์ ์ฆ์ ์ง๋จํ๋ค. - ๋ณ์๊ฐ ์ด๋ค ์ค์ฝํ์์ ํ์๋๋์ง ์ฝ ์คํ์ ๊ทธ๋ฆฌ๋ฉฐ ์ถ์ ํ ์ ์๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
๐ฃ ์์ฒ : "์ํธ ๋, ์ค๋ ์ง์ง ํฉ๋นํ ์ผ์ด ์์์ด์. ์ ๊ฐ
var๋ก ๋ฐ๋ณต๋ฌธ ๋ณ์ ์ ์ธํด์ ๋น๋๊ธฐ ์ฝ๋ฐฑ์์ ์ฐ๋ ์ฝ๋๋ฅผ ์งฐ๋๋ฐ... ๋ฃจํ๊ฐ ๋๋ ๋ค์ ์ฝ๋ฐฑ์ด ์คํ๋๋๊น ๋ณ์๊ฐ ์ ๋ถ ๋ง์ง๋ง ๊ฐ์ผ๋ก ๊ตณ์ด์๋ ๊ฑฐ์์! ์ด๋ป๊ฒ ๋ชจ๋i๊ฐ ๋ค 5์ผ? ๋ถ๋ช 0, 1, 2, 3, 4๊ฐ ์ฐํ์ผ ํ๋๋ฐ... ๋ฉํ์ด ํ๋ค๋ ธ์ต๋๋ค."
๐ฆ ์ํธ: "๊ทธ๊ฑฐ, ์คํ ์ปจํ ์คํธ๋ฅผ ๋ชจ๋ฅด๋ฉด ํ์ ๋นํ๋ ํจ์ ์ด์ผ.
var๋ ํจ์ ์ค์ฝํ ๋ผ์ ๋ฃจํ์{}๋ธ๋ก์ ๋ฌด์ํ๊ณ , ๊ทธ ์ ํจ์(๋๋ ์ ์ญ)์ ๋ฑ ํ๋๋ง ์ ์ธ๋๊ฑฐ๋ . ์ฝ๋ฐฑ์ด ์คํ๋ ๋ ๋ชจ๋ ํด๋ก์ ๊ฐ ๊ฐ์i๋ฅผ ์ฐธ์กฐํ๋๊น ๋น์ฐํ ๋ง์ง๋ง ๊ฐ์ด ๋์ค์ง.let์ ์ฐ๋ฉด ๋ธ๋ก๋ง๋ค ์๋ก์ด ๋ฐ์ธ๋ฉ์ด ์๊ฒจ์ ํด๊ฒฐ๋ผ. ์ด๊ฒ ๋ฐ๋ก ์ค๋ ๋ฐฐ์ธ ์คํ ์ปจํ ์คํธ์ ์ค์ฝํ ์ด์ผ๊ธฐ์ผ."
๐ค 1. ์ ์์์ผ ํ๋๊ฐ?
์์ฒ ์ด๊ฐ ๋ง๋ ๊ฒ์ํ ๋๊ธ ๋ก๋ฉ ์ฝ๋๋ฅผ ๋ณด์.
// ๐ฃ ์์ฒ ์ ์ฝ๋ โ ๋๊ธ 5๊ฐ๋ฅผ ๋น๋๊ธฐ๋ก ๊ฐ๊ฐ ๋ก๋ํ๋ ค ํ์
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log("๋๊ธ " + i + "๋ฒ ๋ก๋ ์๋ฃ"); // ์ค์ ์ถ๋ ฅ: ์ ๋ถ "๋๊ธ 5๋ฒ ๋ก๋ ์๋ฃ"
}, 1000);
}์์ฒ ์ด๋ 0, 1, 2, 3, 4๋ฅผ ๊ธฐ๋ํ์ง๋ง ์ค์ ๋ก๋ 5, 5, 5, 5, 5๊ฐ ์ถ๋ ฅ๋๋ค.
์ด ๋ฒ๊ทธ์ ์์ธ์ ๋จ ํ๋:
var๋ ๋ธ๋ก ์ค์ฝํ๊ฐ ์๋ค. ๋ฃจํ๊ฐ ๋์๋i๋ ์ ์ญ(๋๋ ํจ์) ์ปจํ ์คํธ์ ํ๋๋ง ์กด์ฌํ๊ณ , setTimeout ์ฝ๋ฐฑ์ด ์คํ๋ ๋๋ ์ด๋ฏธ ๋ฃจํ๊ฐ ๋๋i === 5์ํ๋ค.
์คํ ์ปจํ ์คํธ์ ์ค์ฝํ๋ฅผ ์ดํดํ๋ฉด ์ด๋ฐ ๋ณด์ด์ง ์๋ ํจ์ ์ ์ค๊ณ ๋จ๊ณ์์ ์ฐจ๋จํ ์ ์๋ค.
๐๏ธ 2. ์คํ ์ปจํ ์คํธ๋?
JS ์์ง์ด ์ฝ๋๋ฅผ ์คํํ ๋ ๋ง๋๋ ํ๊ฒฝ ์ ๋ณด ๋ฌถ์ ์ด๋ค. "์ด ์ฝ๋๊ฐ ์ด๋ค ๋ณ์์ ์ ๊ทผํ ์ ์๋๊ฐ?", "this๋ ๋ฌด์์ ๊ฐ๋ฆฌํค๋๊ฐ?"๋ฅผ ๋ด๊ณ ์๋ค.
์คํ ์ปจํ ์คํธ๋ ๋ ๋จ๊ณ ๋ก ์์ฑ๋๋ค:
| ๋จ๊ณ | ์ด๋ฆ | ํ๋ ์ผ |
|---|---|---|
| 1๋จ๊ณ | ์์ฑ ๋จ๊ณ (Creation Phase) | ๋ณ์/ํจ์ ๋ฑ๋ก(ํธ์ด์คํ
), this ๊ฒฐ์ |
| 2๋จ๊ณ | ์คํ ๋จ๊ณ (Execution Phase) | ์ฝ๋๋ฅผ ์์์ ์๋๋ก ํ ์ค์ฉ ์คํ |
ํต์ฌ ๋ฉํ ๋ชจ๋ธ: JS ์์ง์ ์ฝ๋๋ฅผ ๋ ๋ฒ ํ๋๋ค. ์ฒซ ๋ฒ์งธ ํ์ ๋ ๋ณ์/ํจ์๋ฅผ ๋ฏธ๋ฆฌ ๋ฑ๋กํด๋๊ณ , ๋ ๋ฒ์งธ ํ์ ๋ ์ค์ ๋ก ์คํํ๋ค.
์ ์ญ ์คํ ์ปจํ ์คํธ (GEC)
์ฝ๋๊ฐ ์คํ๋๊ธฐ ์ , JS ์์ง์ด ๊ฐ์ฅ ๋จผ์ ๊ตฌ์ถํ๋ ๊ธฐ์ด ํ ๋์
๋๋ค. ์ด ๋จ๊ณ์์ var๋ก ์ ์ธ๋ ๋ณ์๋ ํจ์ ์ ์ธ๋ฌธ๋ค์ด ๋ฉ๋ชจ๋ฆฌ์ ๋ฑ๋ก๋ฉ๋๋ค.
์ ์ญ ์คํ ์ปจํ
์คํธ (GEC)
โโโ VariableEnvironment (var ์ ์ธ๋ค)
โ โโโ userName: undefined โ ํธ์ด์คํ
๋จ
โ โโโ getUserCount: function โ ํจ์ ์ ์ธ์์ ์์ ํ ์ฌ๋ผ์ด
โโโ LexicalEnvironment (let/const ์ ์ธ๋ค)
โ โโโ POST_LIMIT: <uninitialized> โ TDZ ์ํ
โโโ ThisBinding: window (๋ธ๋ผ์ฐ์ ) / global (Node.js)
ํจ์ ์คํ ์ปจํ ์คํธ (FEC)
ํจ์๊ฐ ํธ์ถ๋ ๋๋ง๋ค, ๊ทธ ํจ์๋ง์ ์ํ ์ ์ฉ ๊ณต๊ฐ์ด ์๋ก ์๊น๋๋ค. ์์ฒ ์ด๊ฐ ์๋ก์ด ์ ์ ํ๋กํ ๋ก๋ ํจ์๋ฅผ ๋ง๋ค์์ ๋์ ์ปจํ ์คํธ ๋ด๋ถ๋ฅผ ๋ค์ฌ๋ค๋ณด๊ฒ ์ต๋๋ค.
function loadUserProfile(userId) {
const user = findUser(userId); // ์ด ํจ์๊ฐ ํธ์ถ๋๋ฉด ์ ์ปจํ
์คํธ ์์ฑ
return user;
}
// loadUserProfile(42) ํธ์ถ ์:
// ํจ์ ์คํ ์ปจํ
์คํธ (FEC)
// โโโ Arguments: { userId: 42 }
// โโโ LexicalEnvironment: { user: <uninitialized> }
// โโโ OuterEnvironment: โ ์ ์ญ ์คํ ์ปจํ
์คํธ (์ค์ฝํ ์ฒด์ธ)์ฝ ์คํ (Call Stack)
์์ฑ๋ ์คํ ์ปจํ ์คํธ๋ค์ ์ฐจ๊ณก์ฐจ๊ณก ์์ด๊ฒ ๋ฉ๋๋ค. ์์๋ค ์ปค๋ฎค๋ํฐ์์ ๊ฒ์๊ธ ์์ธ ์กฐํ๋ฅผ ๋๋ฅด๋ ์๊ฐ, ๋ธ๋ผ์ฐ์ ๋ด๋ถ์์ ์ด๋ค ์ผ์ด ์ผ์ด๋๋์ง ์๊ฐํํด ๋ณด๊ฒ ์ต๋๋ค.
// ์์๋ค ์ปค๋ฎค๋ํฐ โ ๊ฒ์๊ธ ์์ธ ์กฐํ ํ๋ฆ
function getComments(postId) {
return fetchFromDB(postId); // fetchFromDB ํธ์ถ
}
function renderPost(postId) {
const comments = getComments(postId); // getComments ํธ์ถ
return { comments };
}
renderPost(101);
// ์ฝ ์คํ ์๊ฐํ:
// โโโโโโโโโโโโโโโโโโโโโโโ
// โ fetchFromDB (FEC) โ โ ํ์ฌ ์คํ ์ค (top)
// โโโโโโโโโโโโโโโโโโโโโโโค
// โ getComments (FEC) โ
// โโโโโโโโโโโโโโโโโโโโโโโค
// โ renderPost (FEC) โ
// โโโโโโโโโโโโโโโโโโโโโโโค
// โ ์ ์ญ ์ปจํ
์คํธ (GEC) โ โ ํญ์ bottom
// โโโโโโโโโโโโโโโโโโโโโโโ
//
// fetchFromDB ์๋ฃ โ pop
// getComments ์๋ฃ โ pop
// renderPost ์๋ฃ โ pop
// ์ ์ญ๋ง ๋จ์๐ 3. ํธ์ด์คํ โ ์ ์ธ์ด ์๋ก ๋๋ ค์ฌ๋ผ๊ฐ๋ค?
ํธ์ด์คํ ์ "์ฝ๋๊ฐ ๋ฌผ๋ฆฌ์ ์ผ๋ก ์๋ก ์ด๋" ํ๋ ๊ฒ ์๋๋ค. ์คํ ์ปจํ ์คํธ์ ์์ฑ ๋จ๊ณ ์์ ๋ณ์์ ํจ์๊ฐ ๋ฏธ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ์ ๋ฑ๋ก๋๋ ๊ฒ์ด๋ค.
var ์ ํธ์ด์คํ ํญํ
var ๋ ์ ์ธ๋๊ธฐ ์ ๋ถํฐ ๋ง์น ์ด๋ฏธ ์กด์ฌํ๋ ๊ฒ์ฒ๋ผ ํ๋ํฉ๋๋ค. ์๋ฌ๋ฅผ ๋ด๋ฑ๋ ๋์ undefined๋ฅผ ๋ฐํํ๋ฉฐ ์กฐ์ฉํ ๋ฒ๊ทธ๋ฅผ ์จ๊ธฐ๊ณค ํ๋๋ฐ, ์ํธ ๋ฆฌ๋ ๋์ ์ด๋ฅผ "์ธ์ ํฐ์ง์ง ๋ชจ๋ฅด๋ ์ํํญํ ๊ฐ์ ์ฝ๋"๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
// โ ์์งํ ์ฝ๋ (Naive Approach) โ ์์ฒ ์ด์ ์ด๊ธฐ ์ฝ๋
console.log(userName); // undefined (์๋ฌ๊ฐ ์๋! ์ด๊ฒ ๋ ๋ฌด์์)
var userName = "์์ฒ ";
console.log(userName); // "์์ฒ "
// ๐ฆ JS ์์ง์ด ์ค์ ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ์ (์์ฑ ๋จ๊ณ์์ ์ด๋ฏธ ๋ฑ๋ก๋จ):
// var userName = undefined; โ ์์ฑ ๋จ๊ณ์์ undefined๋ก ์ด๊ธฐํ
// console.log(userName); // undefined
// userName = "์์ฒ "; โ ์คํ ๋จ๊ณ์์ ๊ฐ ํ ๋น
// console.log(userName); // "์์ฒ "์ ์ด๊ฒ ๋ฌธ์ ์ธ๊ฐ? undefined๊ฐ ์กฐ์ฉํ ๋ฐํ๋๊ธฐ ๋๋ฌธ์, ์ด๋๊ฐ์์ ๋ฐ์ดํฐ๊ฐ ๊ผฌ์ฌ๋ ์์ธ์ ์ฐพ๊ธฐ๊ฐ ๋งค์ฐ ํ๋ค์ด์ง๋๋ค. ํนํ ๋ฐ๋ณต๋ฌธ ์์์ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์์ด ์ธ ๋ ๊ทธ ์ํ์ฑ์ด ๋๋๋ฌ์ง๋๋ค.
// โ var์ ํจ์ ์ค์ฝํ ํจ์ โ ๋ฃจํ ๋ฒ๊ทธ
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 3, 3, 3
}
// โ
let์ผ๋ก ๊ต์ฒด โ ๋ธ๋ก ์ค์ฝํ
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 0, 1, 2
}
// let์ ๋ธ๋ก({})`๋ง๋ค ์๋ก์ด ๋ฐ์ธ๋ฉ์ ์์ฑํ๋ค.
// ๊ฐ ์ดํฐ๋ ์ด์
๋ง๋ค ๋
๋ฆฝ์ ์ธ i๊ฐ ์กด์ฌํจ.ํจ์ ์ ์ธ์ vs ํจ์ ํํ์ ์ฐจ์ด
ํจ์๋ฅผ ์ ์ํ๋ ๋ฐฉ์์ ๋ฐ๋ผ ์์ง์ ๋์ฐ๊ฐ ๋ฌ๋ผ์ง๋๋ค. ์ด๋ค ๋ ์์ ํ์ผ ์ต์๋จ์์ ๋ถ๋ฌ๋ ์ฉ์ฉํ๊ฒ ๋ตํ์ง๋ง, ์ด๋ค ๋ ์์ "์์ง ์ค๋น๊ฐ ์ ๋๋ค"๋ฉฐ ์๋ฌ๋ฅผ ๋ด๊ธฐ๋ ํฉ๋๋ค.
// โ
ํจ์ ์ ์ธ์ โ ์์ ํ ํธ์ด์คํ
๋จ (์ ์๊น์ง ์ฌ๋ผ์ด)
sayHello(); // "์๋
ํ์ธ์!" โ ์ ์ธ ์ ์ ํธ์ถํด๋ ์ ์ ์๋
function sayHello() {
console.log("์๋
ํ์ธ์!");
}
// โ ํจ์ ํํ์ โ ๋ณ์๋ง ํธ์ด์คํ
๋จ (undefined ์ํ)
sayBye(); // TypeError: sayBye is not a function
var sayBye = function () {
console.log("์๋
ํ ๊ฐ์ธ์!");
};
// โ const/let + ํ์ดํ ํจ์ โ TDZ๋ก ์ธํด ReferenceError
greet(); // ReferenceError: Cannot access 'greet' before initialization
const greet = () => {
console.log("๋ฐ๊ฐ์ต๋๋ค!");
};๐ฆ ์ํธ์ ์กฐ์ธ: "ํจ์ ์ ์ธ์์ ํธ์ด์คํ ๋๋ถ์ ํ์ผ ์๋์ชฝ์ ํฌํผ ํจ์๋ฅผ ๋ชจ์๋๋ ์คํ์ผ์ด ๊ฐ๋ฅํ๊ธด ํด. ํ์ง๋ง ํ ํ๋ก์ ํธ์์๋ ์ ์ธ ์์๊ฐ ์๋๋ฅผ ์ ๋ฌ ํ๋ฏ๋ก, ์ผ๊ด์ฑ์ ์ํด ํจ์ ํํ์(
const fn = () => {})์ ์ ํธํ๋ ํ๋ ๋ง์."
๐๏ธ 4. ์ค์ฝํ & ์ค์ฝํ ์ฒด์ธ
์ค์ฝํ (Scope) ๋ ๋ณ์๊ฐ ์ ํจํ ์์ญ์ด๋ค. JS๋ ๋ ์์ปฌ ์ค์ฝํ ๋ฅผ ์ฌ์ฉํ๋ค.
๋ ์์ปฌ ์ค์ฝํ (Lexical Scope)
ํจ์๊ฐ ์ด๋์ ํธ์ถ๋๋์ง๋ ์ค์ํ์ง ์์ต๋๋ค. ์ค์ง ์ด๋์ ํ์ด๋ฌ๋๊ฐ ๊ฐ ๋ณ์์ ์ด๋ช ์ ๊ฒฐ์ ํฉ๋๋ค. ์์๋ค ์ปค๋ฎค๋ํฐ์ ๊ถํ ์ฒดํฌ ๋ก์ง์ ํตํด ์ด ๊ด๊ณ๋ฅผ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
// ์์๋ค ์ปค๋ฎค๋ํฐ โ ๊ถํ ์ฒดํฌ ๋ก์ง
const APP_NAME = "์์๋ค ์ปค๋ฎค๋ํฐ"; // ์ ์ญ ์ค์ฝํ
function checkAuth() {
const role = "admin"; // checkAuth ์ค์ฝํ
function showWelcome() {
// role์ ์ ์ธํ ์ ์์ง๋ง, ์ ์ธ๋ ์์น(์์ ์ค์ฝํ)์์ ์ฐพ์์ด
console.log(`${APP_NAME}์ ์ค์ ${role} ๋ ํ์ํฉ๋๋ค!`);
// โ "์์๋ค ์ปค๋ฎค๋ํฐ์ ์ค์ admin ๋ ํ์ํฉ๋๋ค!"
}
showWelcome();
}
checkAuth();
// ์ค์ฝํ ์ฒด์ธ ํ์ ์์:
// showWelcome โ checkAuth โ ์ ์ญ
// role: showWelcome์ ์์ โ checkAuth์์ ๋ฐ๊ฒฌ โ
// APP_NAME: showWelcome์ ์์ โ checkAuth์ ์์ โ ์ ์ญ์์ ๋ฐ๊ฒฌ โ
var / let / const ์ค์ฝํ ๋น๊ต
var | let | const | |
|---|---|---|---|
| ์ค์ฝํ | ํจ์ ์ค์ฝํ | ๋ธ๋ก ์ค์ฝํ | ๋ธ๋ก ์ค์ฝํ |
| ํธ์ด์คํ | โ (undefined ์ด๊ธฐํ) | โ (TDZ, ์ด๊ธฐํ ์ ๋จ) | โ (TDZ, ์ด๊ธฐํ ์ ๋จ) |
| ์ฌ์ ์ธ | โ ๊ฐ๋ฅ | โ ๋ถ๊ฐ | โ ๋ถ๊ฐ |
| ์ฌํ ๋น | โ ๊ฐ๋ฅ | โ ๊ฐ๋ฅ | โ ๋ถ๊ฐ |
| ์ค๋ฌด ๊ถ์ฅ | โ ์ฌ์ฉ ๊ธ์ง | โ ๋ณ๊ฒฝ ํ์ํ ๋ณ์ | โ ๊ธฐ๋ณธ๊ฐ (๋๋ถ๋ถ ์ด๊ฑธ ์จ๋ผ) |
// โ var โ ๋ธ๋ก์ ๋ฌด์ํ๋ ์ํํ ํ๋
function processPost() {
if (true) {
var tempData = "์์ ๋ฐ์ดํฐ"; // if ๋ธ๋ก ๋ฐ์์๋ ์ ๊ทผ ๊ฐ๋ฅ!
}
console.log(tempData); // "์์ ๋ฐ์ดํฐ" โ ์๋์น ์์ ์ ๊ทผ
}
// โ
let/const โ ๋ธ๋ก ๊ฒฝ๊ณ๋ฅผ ์งํจ๋ค
function processPost() {
if (true) {
const tempData = "์์ ๋ฐ์ดํฐ"; // if ๋ธ๋ก ๋ด๋ถ์์๋ง ์ ํจ
}
console.log(tempData); // ReferenceError: tempData is not defined โ ๋ช
ํํ ์๋ฌ!
}TDZ โ Temporal Dead Zone
let๊ณผ const๋ ์ฌ์ค ํธ์ด์คํ
์ ๋์ง๋ง, ์์ ์ ์ํด "์ ์ธ๋ฌธ์ด ์คํ๋๊ธฐ ์ ๊น์ง๋ ๋ง์ง์ง ๋ง์์ค" ๋ผ๋ ์ผ์์ ์ฌ๊ฐ์ง๋๋ฅผ ๋ง๋ญ๋๋ค.
// TDZ ์๊ฐํ
{
// โ ์ฌ๊ธฐ์๋ถํฐ TDZ ์์ (postTitle์ ๋ฉ๋ชจ๋ฆฌ์ ๋ฑ๋ก๋์ง๋ง ์ด๊ธฐํ ์ ๋จ)
console.log(postTitle); // โ ReferenceError: Cannot access 'postTitle' before initialization
const postTitle = "ํด๋ก์ ์์ ์ ๋ณต"; // โ ์ฌ๊ธฐ์ TDZ ์ข
๋ฃ, ์ด๊ธฐํ
console.log(postTitle); // โ
"ํด๋ก์ ์์ ์ ๋ณต"
}
// ์ TDZ๊ฐ ์ข์๊ฐ?
// var: ์ ์ธ ์ ์ ๊ทผ โ undefined (์กฐ์ฉํ ๋ฒ๊ทธ)
// let/const: ์ ์ธ ์ ์ ๊ทผ โ ReferenceError (์ฆ์ ๋ฐ๊ฒฌ๋๋ ๋ช
ํํ ์๋ฌ) โ
๐ 5. ์ค๋ฌด ํจํด ์ ๋ฆฌ
์ง๊ธ๊น์ง ๋ฐฐ์ด ๊ฐ๋ ๋ค์ ์ค๋ฌด ์ฝ๋์ ์ด๋ป๊ฒ ๋ น์ฌ๋ด์ผ ํ ๊น์? ์ํธ ๋ฆฌ๋ ๋์ด ํ์๋ค์๊ฒ ๊ณต์ ํ "์ ๋ ๋ฌด๋์ง์ง ์๋ ๋ณ์ ์ ์ธ ์ ๋ต"์ ์๊ฐํฉ๋๋ค.
// โ
์ค๋ฌด์์ ๊ถ์ฅํ๋ ๋ณ์ ์ ์ธ ์ ๋ต
// 1. ๊ธฐ๋ณธ์ const โ ๋๋ถ๋ถ์ ๋ณ์๋ ์ฌํ ๋น ๋ถํ์
const API_BASE_URL = "https://api.youngsu.com";
const currentUser = { id: 42, name: "์์ฒ " };
// 2. ์ฌํ ๋น์ด ํ์ํ ๊ฒฝ์ฐ๋ง let
let retryCount = 0;
while (retryCount < 3) {
// ...
retryCount++;
}
// 3. var๋ ์ ๋ ์ฌ์ฉ ๊ธ์ง
// var isLoading = true; โ ์ด ์ฝ๋๊ฐ PR์ ์ฌ๋ผ์ค๋ฉด ์ํธ ๋ฆฌ๋๊ฐ reject
// 4. ํจ์๋ const + ํ์ดํ ํจ์๋ก ์ผ๊ด์ฑ ์ ์ง
const fetchPost = async (postId) => {
const response = await fetch(`${API_BASE_URL}/posts/${postId}`);
return response.json();
};
// 5. for...of ๋ฃจํ์์๋ const ์ฌ์ฉ ๊ฐ๋ฅ (๋งค ์ดํฐ๋ ์ด์
๋ง๋ค ์ ๋ฐ์ธ๋ฉ)
const posts = [{ id: 1 }, { id: 2 }, { id: 3 }];
for (const post of posts) {
console.log(post.id); // 1, 2, 3
}๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. ์๋ ์ฝ๋์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ์์ธกํ๊ณ , ๊ทธ ์ด์ ๋ฅผ ์ค๋ช ํ๋ผ.
console.log(a);
console.log(b);
var a = 1;
let b = 2;โ
์ ๋ต: undefined ์ถ๋ ฅ ํ, ReferenceError: Cannot access 'b' before initialization
๐ก ์์ธ ํด์ค:
var a์ ํธ์ด์คํ : ์์ฑ ๋จ๊ณ์์a๋undefined๋ก ์ด๊ธฐํ๋์ด ๋ฉ๋ชจ๋ฆฌ์ ๋ฑ๋ก๋๋ค. ๋ฐ๋ผ์ ์ ์ธ ์ ์ ๊ทผํด๋undefined๋ฅผ ๋ฐํํ๋ค.let b์ TDZ:b๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ฑ๋ก๋์ง๋ง ์ด๊ธฐํ๋์ง ์์ ์ํ(uninitialized) ๋ก TDZ ๊ตฌ๊ฐ์ ์๋ค. ์ ์ธ๋ฌธ ์คํ ์ ์ ์ ๊ทผํ๋ฉดReferenceError๊ฐ ๋ฐ์ํ๋ค.- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ:
var๋ "์กฐ์ฉํundefined",let/const๋ "์๋๋ฌ์ด ์๋ฌ". ์๋๋ฌ์ด ์๋ฌ๊ฐ ๋ ์ข๋ค. ๋ฒ๊ทธ๋ฅผ ์ฆ์ ๋ฐ๊ฒฌํ ์ ์์ผ๋๊น.
Q2. ๋ ์์ปฌ ์ค์ฝํ์ ๋์ ์ค์ฝํ์ ์ฐจ์ด๋? JavaScript๋ ์ด๋ ์ชฝ์ธ๊ฐ?
โ ์ ๋ต: JavaScript๋ ๋ ์์ปฌ ์ค์ฝํ (์ ์ ์ค์ฝํ)
๐ก ์์ธ ํด์ค:
- ๋ ์์ปฌ ์ค์ฝํ: ํจ์๊ฐ ์ ์ธ๋ ์์น ๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ ์ค์ฝํ๋ฅผ ๊ฒฐ์ ํ๋ค. ์ฝ๋๋ฅผ ์์ฑํ ๋(์ ์ ์ผ๋ก) ์ค์ฝํ๊ฐ ํ์ ๋๋ค.
- ๋์ ์ค์ฝํ: ํจ์๊ฐ ํธ์ถ๋ ์์น ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค์ฝํ๋ฅผ ๊ฒฐ์ ํ๋ค. (JavaScript๋ ์ด ๋ฐฉ์ ์ฌ์ฉ ์ ํจ)
- JS๋ ๋ ์์ปฌ ์ค์ฝํ์ด๋ฏ๋ก, ํจ์๋ฅผ ์ด๋์์ ํธ์ถํ๋ ์ ์ธ๋ ์์น์ ์์ ์ค์ฝํ ๋ฅผ ์ฐธ์กฐํ๋ค. ์ด๊ฒ์ด ํด๋ก์ ์ ๊ทผ๊ฐ์ด๋ค.
- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "ํจ์๊ฐ ํ์ด๋ ๊ณณ์ ๊ธฐ์ตํ๋ค." โ ํด๋ก์ ์ฑํฐ์์ ์ด ๊ฐ๋ ์ด ํญ๋ฐ์ ์ผ๋ก ํ์ฅ๋๋ค.
Q3. ์์ฒ ์ด์ ํ ์คํธ ํ์ โ ๊ธด๊ธ ๋๋ฒ๊น
์์ PM์ด ํธํต์ ์น๋ค: "์์ฒ ๋, ๊ด๋ฆฌ์ ํ์ด์ง์์
isAdmin์ฒดํฌ๊ฐ ์์ ํ ๋ซ๋ ธ์ด์! ๋ฃจํ ์์์ ๊ถํ ์ฒดํฌํ๋ ์ฝ๋๋ฅผ ๋ณด๋ด์ค์!"
// ๐ฃ ์์ฒ ์ด ๋ณด๋ธ ์ฝ๋
var isAdmin = false;
for (var i = 0; i < adminList.length; i++) {
if (adminList[i].id === currentUser.id) {
var isAdmin = true; // ์ฌ์ ์ธํด๋ ์๋ฌ ์์!
}
}
setTimeout(() => {
if (isAdmin) {
showAdminPanel(); // ์๋๋ ๋ง์ง๋ง ๊ตฌ์กฐ ์์ฒด๊ฐ ์ํ
}
}, 0);์ด๋ค ๋ฌธ์ ๊ฐ ์๋๊ฐ? ์ด๋ป๊ฒ ๋ฆฌํฉํ ๋งํด์ผ ํ๋๊ฐ?
โ
์ ๋ต: var ์ฌ์ ์ธ ํ์ฉ + ํจ์ ์ค์ฝํ๋ก ์ธํ ๊ตฌ์กฐ์ ์ทจ์ฝ์ . const์ Array.some()์ผ๋ก ๊ต์ฒด.
๐ก ์์ธ ํด์ค:
var isAdmin์ฌ์ ์ธ:var๋ ๊ฐ์ ์ค์ฝํ ๋ด์์ ์ค๋ณต ์ ์ธ์ด ํ์ฉ๋๋ค. ๋๊ท๋ชจ ์ฝ๋๋ฒ ์ด์ค์์ ๋ค๋ฅธ ๊ฐ๋ฐ์๊ฐ ์ค์๋ก ๊ฐ์ ์ด๋ฆ์var๋ฅผ ์ ์ธํ๋ฉด ์กฐ์ฉํ ๋ฎ์ด์ด๋ค. ๋ณด์ ๋ฒ๊ทธ์ ์จ์ ์ด๋ค.- ๋ ๋์ ํจํด (Pro Approach):
// โ ๋ฆฌํฉํ ๋ง๋ ์ฝ๋ const isAdmin = adminList.some((admin) => admin.id === currentUser.id); // - const: ์ฌํ ๋น/์ฌ์ ์ธ ๋ถ๊ฐ โ ์๋์น ์์ ๋ณ๊ฒฝ ๋ฐฉ์ง // - some(): ์กฐ๊ฑด ์ถฉ์กฑ ์ฆ์ ์ํ ์ค๋จ (์ฑ๋ฅ โ ) // - ํจ์ํ: ์์ ํํ์์ผ๋ก ๊ฐ๋ ์ฑ ๊ทน๋ํ - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "์ธ์ฆ์ด๋ ๋ณด์์ ๊ด๋ จ๋ ๋ณ์๋ ๋ฐ๋์
const๋ก ๊ด๋ฆฌํด์ผ ํฉ๋๋ค."var๋ ๋๋ ๋ชจ๋ฅด๋ ์ฌ์ด์ ๋ค๋ฅธ ์ฝ๋์ ์ํด ๊ฐ์ด ๋ฎ์ด์จ์ง ์ํ์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
ํด๊ทผ๊ธธ ๋ฒ์ค์ ์์๋ค. ์ค๋ ์ํธ ๋์ด "์คํ ์ปจํ
์คํธ" ์ค๋ช
ํด์ฃผ๋ ๊ฑฐ ๋ฃ๊ณ , ์์งํ ์ฒ์์๋ '์ด๊ฒ ๋ญ ์ฒ ํ ์์
์ด์ผ...' ์ถ์๋๋ฐ. ์ง๊ธ ๋์๋ณด๋๊น ๋ด๊ฐ ๊ทธ๋์ ์ผ๋ง๋ ์๋ฌด๊ฒ๋ ๋ชจ๋ฅด๊ณ ์ฝ๋๋ฅผ ์งฐ๋์ง๊ฐ ๋๊ปด์ ธ์ ์ข ๋ฏผ๋งํ๋ค. var๋ก ๋ฃจํ ๋๋ฆฌ๊ณ ๋น๋๊ธฐ ์ด ์ฝ๋๊ฐ... ํ ํ๋ก์ ํธ ๋ ํฌ์ ์์ง ์ด์์์ ํ
๋ฐ. ๋ด์ผ ์ถ๊ทผํ์๋ง์ ์กฐ์ฉํ PR ์ฌ๋ ค์ผ๊ฒ ๋ค.
๐ก ์ค๋์ ๊ตํ: "JS ์์ง์ ์ฝ๋๋ฅผ ๋ ๋ฒ ์ฝ๋๋ค. ์ฒซ ๋ฒ์งธ๋ ๋ณ์๋ฅผ ๋ฑ๋กํ๊ณ , ๋ ๋ฒ์งธ๋ ์คํํ๋ค.
var๋ ์ฒซ ๋ฒ์งธ ๋undefined๋ก ์กฐ์ฉํ ๋ค์ด์ค๊ณ ,let/const๋ TDZ๋ก ์๋๋ฝ๊ฒ ์๊ธฐ ์กด์ฌ๋ฅผ ์๋ฆฐ๋ค. ์๋๋ฌ์ด ์ชฝ์ด ์คํ๋ ค ์ฐฉํ ๊ฑฐ๋ค."
์ํธ ๋ ๋๋ถ์ ์ด์๋ค. ์ค๋ ํ ๊ฑด ๋ฐฐ์ ์ผ๋๊น, ์ง ๊ฐ์ ๋งฅ์ฃผ ํ ์บ ๋ฐ๊ณ ๋ค์ ์ฑํฐ ํ ๋ฒ๋ง ๋ ํ์ด๋ด์ผ์ง. ํด๋ก์ ๊ฐ ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ค๊ณ .