
๐ JavaScript ํจ์์ ํธ์ด์คํ (Hoisting)
์๋ฐ์คํฌ๋ฆฝํธ์์ ํจ์๋ฅผ ์ ์ธํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ์์ ๋ค๋ฅธ ์ธ์ด์ ๋น๊ตํ์ ๋ ์กฐ๊ธ ํน์ดํ๋ค.
ํนํ ํธ์ด์คํ (Hoisting)์ด๋ผ๋ ๊ธฐ๋ฅ ๋๋ถ์, ํจ์ ์ ์ธ์ด ์ฝ๋ ์คํ ์์ ๋ณด๋ค ๋ค์ ์์ด๋ ์ ์์ ์ผ๋ก ํธ์ถ์ด ๊ฐ๋ฅํ๋ค.
๋ฐ๋ผ์ ์ด๋ฒ ํฌ์คํ ์์๋ ์์ ์ฝ๋๋ฅผ ํตํด ํจ์ ํธ์ถ, ์ค์ฒฉ ํจ์, ๊ทธ๋ฆฌ๊ณ ํธ์ด์คํ ์ ๋ํด ์ ๋ฆฌํด๋ณด๊ณ ์ ํ๋ค.
๐ช ํจ์ ์ ์ธ๊ณผ ํธ์ถ
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํจ์๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ธํ๊ณ ํธ์ถํ ์ ์๋ค.
function getArea(width, height) {
let area = width * height;
return area;
}
let area1 = getArea(10, 20);
console.log(area1); // 200
let area2 = getArea(30, 20);
console.log(area2); // 600
getArea๋ผ๋ ํจ์๋ width์ height๋ฅผ ๋ฐ์์ ๋์ด๋ฅผ ๊ณ์ฐํ ๋ค ๋ฐํํด์ค๋ค.
ํจ์ ํธ์ถ์ ํจ์๋ช (์ธ์) ํํ๋ก ์คํํ๋ฉฐ, ๋ฐํ๋ ๊ฐ์ ๋ณ์์ ์ ์ฅํ ์ ์๋ค.
๐ ์ฐธ๊ณ
์๋ฐ์คํฌ๋ฆฝํธ์์๋ ํจ์๋ ์ผ๊ธ ๊ฐ์ฒด(First-class Citizen)์ด๊ธฐ ๋๋ฌธ์
๊ฐ์ฒ๋ผ ๋ณ์์ ํ ๋นํ๊ฑฐ๋ ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ์ ๋ฌํ ์ ์๋ค.
// ํจ์ ์์ฒด๋ฅผ ๋ณ์์ ํ ๋น
let greet = function() {
console.log("์๋
ํ์ธ์!");
};
greet(); // "์๋
ํ์ธ์!"
function multiplier(factor) {
return function(number) {
return number * factor;
};
}
let double = multiplier(2);
console.log(double(5)); // 10
let triple = multiplier(3);
console.log(triple(5)); // 15
๐จ ์ค์ฒฉ ํจ์ (Nested Function)
์๋ฐ์คํฌ๋ฆฝํธ์์๋ ํจ์ ์์ ๋ ๋ค๋ฅธ ํจ์๋ฅผ ์ ์ธํ ์ ์๋๋ฐ, ์ด๋ฅผ ์ค์ฒฉ ํจ์๋ผ๊ณ ํ๋ค.
function outer() {
console.log("outer function");
function inner() {
console.log("inner function");
}
inner();
}
outer();
// ์ถ๋ ฅ ๊ฒฐ๊ณผ
// "outer function"
// "inner function"
์ด๋ ๊ฒ ์ ์ธ๋ inner ํจ์๋ ์ค์ง outer ํจ์ ์์์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.
์ด๋ฅผ ํ์ฉํ๋ฉด ์ธ๋ถ์์ ์ง์ ํธ์ถํ ์ ์์ผ๋ฏ๋ก ์บก์ํ(encapsulation)ํจ๊ณผ๋ฅผ ๋ผ ์ ์๊ณ ,
์ธ๋ถ์์ ๋ถํ์ํ๊ฒ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ๋ง์ ์๋ ์๋ค.
๐ฅ ํธ์ด์คํ (Hoisting)์ด๋
ํธ์ด์คํ ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ ์
๋ณ์์ ํจ์ ์ ์ธ์ ๋ฉ๋ชจ๋ฆฌ์ ์ต์๋จ์ผ๋ก ๋์ด์ฌ๋ฆฌ๋ ๋์์ ๋งํ๋ค.
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
์ด์ฒ๋ผ sayHello ํจ์๊ฐ ์ ์ธ๋๊ธฐ ์ ์ ํธ์ถํด๋ ์ ์์ ์ผ๋ก ์ ์คํ๋๋ค.
๐ ์ฐธ๊ณ
๊ทธ๋ฌ๋ ๋ชจ๋ ํจ์๊ฐ ๋๊ฐ์ด ํธ์ด์คํ ๋๋ ๊ฒ์ ์๋๋ค.
greet(); // "Hi"
function greet() {
console.log("Hi");
}
greet(); // โ TypeError: greet is not a function
let greet = function() {
console.log("Hi");
};
๋ ์์ ์ฝ๋์ ์ฐจ์ด๊ฐ ๋ญ๊น?
๋ฐ๋ก ์ฒซ ๋ฒ์งธ ์์ ์ฝ๋๋ ํจ์ ์ ์ธ๋ฌธ์ด์ด์ ํธ์ด์คํ ์ด ๋์ง๋ง,
๋ ๋ฒ์งธ ์์ ์ฝ๋๋ ํจ์ ํํ์์ด๋ผ๋ ์ ์ด๋ค.
๊ทธ๋์ ๋ ๋ฒ์งธ ์์ ์ฝ๋์์๋ ํจ์ ํํ์์ด ๋ณ์๋ก ์ทจ๊ธ๋๊ธฐ ๋๋ฌธ์
ํธ์ด์คํ ์์ ์ undefined๋ก ์ด๊ธฐํ๋์ด ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
(ํ์ดํ ํจ์ ๋ํ ํจ์ ํํ์์ด๊ธฐ ๋๋ฌธ์ ๋์ผํ ๊ท์น์ด ์ ์ฉ๋๋ค.)
๐ ์ฐธ๊ณ
๋ํ, ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ ์ var๋ ํธ์ด์คํ ํ๋ค๊ณ ํ๋ค.
console.log(a); // undefined
var a = 10;
console.log(a); // 10
๋ด๋ถ์ ์ผ๋ก๋ ์๋์ ๊ฐ์ ์์๋ก ๋์ํ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
var a; // ์ ์ธ๋ง ์๋ก ๋์ด์ฌ๋ ค์ง (undefined๋ก ์ด๊ธฐํ)
console.log(a); // undefined
a = 10;
console.log(a); // 10
์ด์ฒ๋ผ var๋ ํธ์ด์คํ ์ ์๋์ผ๋ก undefined๋ก ์ด๊ธฐํ๋๊ธฐ ๋๋ฌธ์
์ ์ธ ์ ์ ์ ๊ทผํด๋ ์๋ฌ๊ฐ ๋๋๊ฒ ์๋๋ผ undefined๊ฐ ๋์จ๋ค.
๋ฌธ์ ๋, ์ด๋ ๊ฒ ๋๋ฉด ์ค์๋ก ์ ์ธ ์ ์ ์ ๊ทผํ์ ๋ ๋ฒ๊ทธ๋ฅผ ๋ฐ๊ฒฌํ๊ธฐ ์ด๋ ต๋ค๋ ์ ์ด๋ค.
๊ทธ๋์ ๋ณดํต์ let๊ณผ const๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค๊ณ ํ๋ค.
๋ฌผ๋ก , let๊ณผ const๋ ์ฌ์ค ์ ์ธ ์์ฒด๋ ํธ์ด์คํ ๋๊ธฐ๋ ํ์ง๋ง,
ํธ์ด์คํ ๋ ์์ ๋ถํฐ ์ค์ ์ ์ธ๋ฌธ์ด ์คํ๋๊ธฐ ์ ๊น์ง ์ผ์์ ์ฌ๊ฐ์ง๋(TDZ)์ ๋จธ๋ฌผ๊ธฐ ๋๋ฌธ์ ๋ฌด์กฐ๊ฑด ์๋ฌ๋ฅผ ๋์ ธ์ค๋ค๊ณ ํ๋ค.
console.log(b); // โ ReferenceError: Cannot access 'b' before initialization
let b = 10;
console.log(b); // 10
๋ด๋ถ์ ์ผ๋ก๋ ์๋์ ๊ฐ์ ์์๋ก ๋์ํ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
// b๋ ํธ์ด์คํ
๋์์ง๋ง, TDZ์ ์๊ธฐ ๋๋ฌธ์ ์ ์ธ๋ฌธ์ ๋ง๋๊ธฐ ์ ๊น์ง ์ ๊ทผ ๋ถ๊ฐ
console.log(b); // ReferenceError
let b = 10; // ์ฌ๊ธฐ์ ๋น๋ก์ ์ด๊ธฐํ๋จ
console.log(b); // 10
์ฆ, let๊ณผ const๋ ์ ์ธ๋ง ์๋ก ๋์ด์ฌ๋ ค์ง๊ณ ์ด๊ธฐํ๋ ์ค์ ์ฝ๋ ์์น์์ ๋๋ค๋ ๊ท์น ๋๋ฌธ์
์ ์ธ๋ฌธ ์ด์ ์ ์ ๊ทผํ๋ฉด ๋ฌด์กฐ๊ฑด ์๋ฌ๋ฅผ ๋์ง๋ ๊ฒ์ด๊ณ , ์ด๋ฅผ TDZ๋ผ๊ณ ๋ถ๋ฅด๋ ๊ฒ์ด๋ค.
๐ ๊ฒฐ๋ก
๋ค๋ฅธ ์ธ์ด์์๋ ๋ณด๊ธฐ ํ๋ค์๋ ํธ์ด์คํ ํน์ฑ์ ์ ๋ฆฌํ๊ธฐ๋ ํ์ง๋ง,
๊ทธ๋๋ ์ผ๊ด์ฑ ์๊ฒ ํจ์๋ฅผ ์ ์ํ๋ ๊ฒ ๋ ์ข๋ค๊ณ ์๊ฐํด์
์์ผ๋ก๋ ํ์ผ ์๋จ์ด๋ ๋ชจ๋์ ํจ์ ์ ์ธ์ ๋ชจ์๋๋ ๋ฐฉ์์ ์ธ ๊ฒ ๊ฐ๊ธฐ๋ ํ๋ค.
ํนํ ํจ์ ์ ์ธ๋ฌธ์๋ ํธ์ด์คํ ์ด ์ ์ฉ๋์ง๋ง, ํจ์ ํํ์์๋ ํธ์ด์คํ ์ด ์ ์ฉ๋์ง ์๋๋ค๋ ์ ๋๋ฌธ์
ํธ์ด์คํ ๋๋ถ์ ์ ๋์๊ฐ๋ค์ ์์กดํ๊ธฐ ๋ณด๋ค๋, ํจ์๋ฅผ ๋จผ์ ์ ์ธํ๊ณ ํธ์ถํ๋ ๊ฒ ์ข์ ๊ฒ ๊ฐ๋ค.