티스토리 뷰
목차
JavaScript를 배우다 보면 처음에는 간단하게 느껴지다가도, 어느 순간 예상치 못한 동작을 마주하게 될 때가 있습니다. 그중에서도 많은 사람들이 헷갈려하는 개념 중 하나가 바로 변수 선언과 호이스팅(hoisting)입니다. 오늘은 JavaScript의 변수와 호이스팅에 대해 어렵지 않게, 부드럽게 풀어보겠습니다.
▶ JavaScript의 변수
우선, JavaScript에서 변수를 선언하는 방법부터 간단히 짚고 넘어 가보겠습니다. JavaScript에서는 변수를 선언할 때 var, let, const 세 가지 키워드를 사용할 수 있습니다. 이 세 가지는 변수의 동작 방식을 다르게 만드는데, 특히 호이스팅과 관련해 중요한 차이점이 있습니다.
1. var
var는 JavaScript에서 가장 오래된 변수 선언 방식입니다. 예전부터 사용되어 왔기 때문에 많은 레거시 코드에서 var를 볼 수 있습니다. 하지만 var에는 몇 가지 독특한 특징이 있어 때때로 혼란을 초래할 수 있습니다.
var name = "Alice";
console.log(name); // Alice
↑ 위 코드처럼 var로 변수를 선언하고 값을 할당하면, 그 변수를 어디에서든 접근할 수 있습니다. 하지만 이 var에는 우리가 오늘 이야기할 호이스팅과 관련된 함정이 숨어 있습니다. 그 숨은 함정은 아래 호이스팅 부분에서 확인해보겠습니다.
2. let
ES6(ECMAScript 2015)에서 도입된 let은 var의 단점을 보완한 변수 선언 방식입니다. let은 변수를 블록 스코프(block scope) 내에서만 사용할 수 있도록 제한합니다. 블록 스코프란, 중괄호 {}로 둘러싸인 코드 블록을 의미합니다.
let age = 30;
console.log(age); // 30
let을 사용하면 변수는 선언된 블록 내에서만 유효합니다. 이는 코드의 예측 가능성을 높여주고, 의도치 않은 변수 재선언을 방지할 수 있는 장점이 있습니다.
3. const
const는 상수를 선언할 때 사용됩니다. const로 선언된 변수는 한 번 값을 할당하면 변경할 수 없습니다. 이것은 변수의 불변성을 보장하기 때문에, 중요한 값을 실수로 변경하는 일을 막아줍니다.
const pi = 3.14;
console.log(pi); // 3.14
하지만 const로 선언된 객체나 배열은 그 내부의 속성이나 요소를 변경할 수 있습니다. 단, 변수 자체를 다른 값으로 재할당할 수 없다는 점이 특징입니다.
▶ 호이스팅이란 무엇인가요?
이제 본격적으로 호이스팅(hoisting)에 대해 이야기해보겠습니다. 저도 처음 JavaScript를 공부하기 시작했을 때 이 호이스팅이 굉장히 헷갈렸습니다. 호이스팅은 JavaScript의 독특한 동작 방식 중 하나로, 변수가 코드의 최상단으로 끌어올려지는 것처럼 작동하는 현상을 말합니다.
쉽게 말해서, JavaScript 엔진은 변수를 선언하는 구문을 코드의 맨 위로 끌어올려 먼저 처리합니다. 그 결과, 코드에서 변수를 선언하기 전에 참조할 수 있게 되는 것입니다. 이게 무슨 말인지 헷갈릴 수 있으니, 아래 예제를 통해 알아보겠습니다.
console.log(greeting); // undefined
var greeting = "Hello, world!";
console.log(greeting); // Hello, world!
이 코드를 보면, 첫 번째 console.log는 변수를 선언하기 전에 호출되었는데도 오류가 발생하지 않고 undefined가 출력됩니다.
왜 그럴까요?
바로 호이스팅 때문입니다.
JavaScript는 이 코드를 실행하기 전에 다음과 같이 내부적으로 해석합니다
var greeting;
console.log(greeting); // undefined
greeting = "Hello, world!";
console.log(greeting); // Hello, world!
위에서 언급했던 숨은 함정은 바로 var로 선언된 변수가 코드의 최상단으로 끌어올려진 것처럼 동작하는 겁니다. 그래서 변수 선언 전에 그 변수를 참조할 수 있게 됩니다. 하지만 이때 변수에 값이 할당되기 전이기 때문에 undefined가 출력되는 것입니다.
▶ let과 const는 호이스팅이 어떻게 다를까?
이쯤 되면 let과 const는 호이스팅과 관련해 어떻게 동작하는지 궁금하실 것입니다. 이 둘도 호이스팅이 일어나긴 하지만, var와는 다르게 처리됩니다. let과 const는 "일시적 사각지대"(Temporal Dead Zone, TDZ)에 갇히게 됩니다.
일시적 사각지대는 변수가 선언되기 전까지 해당 변수를 참조할 수 없는 상태를 의미합니다.
예를 들어, 다음 코드를 보겠습니다.
console.log(name); // ReferenceError
let name = "Alice";
var와 다르게, let으로 선언된 변수를 선언 전에 참조하려고 하면 ReferenceError가 발생합니다. 이는 let이 호이스팅되긴 하지만, 실제로 변수를 사용할 수 있게 되는 시점은 선언 이후로 제한되기 때문입니다.
const도 마찬가지입니다. const는 선언과 동시에 초기화되어야 하므로, 선언 전에 참조하려고 하면 역시 ReferenceError가 발생합니다.
▶ 함수도 호이스팅이 된다?
JavaScript의 함수 호이스팅은 변수 호이스팅과 비슷하지만, 조금 더 흥미로운 차이가 있습니다. JavaScript는 함수 선언문을 코드 실행 전에 모두 끌어올리기 때문에, 함수가 정의되기 전에 호출할 수 있습니다.
예를 들어, 아래와 같은 코드가 있습니다.
greet();
function greet() {
console.log("Hello, world!");
}
이 코드는 오류 없이 "Hello, world!"를 출력합니다. 함수 선언이 코드의 최상단으로 끌어올려지기 때문입니다. 그러나 함수 표현식으로 함수를 정의할 때는 호이스팅이 다르게 작동합니다. 함수 표현식은 변수에 할당된 함수로, 선언 전에 호출하면 ReferenceError가 발생합니다. 따라서 함수 표현식을 사용할 때는 항상 선언 후 호출하는 습관을 들이는 것이 중요합니다.
JavaScript에서 변수와 호이스팅은 알아두면 도움이 되는 중요한 개념입니다. 호이스팅을 이해하면 코드가 어떻게 동작하는지 더 명확하게 파악할 수 있으며, 예기치 않은 오류를 예방할 수 있습니다. var, let, const의 차이점을 이해하고, 호이스팅이 어떻게 작동하는지 알아두면, 더 안정적이고 깔끔한 코드를 작성할 수 있을 것입니다.
이제 JavaScript의 변수와 호이스팅 개념이 좀 더 친숙하게 느껴지셨을 거라고 생각합니다.