자바스크립트의 변수 선언
먼저 자바스크립트 변수 선언자인 var에 대해 알아야한다.
var가 선언된 변수들은 변수가 선언된 실행 컨텍스트(execution context)안에서 만들어진다.
var가 선언되지 않은 변수들은 항상 전역 변수(window객체의 변수)가 된다.
그렇다면 실제 코드를 봐보자!
1
2
var v1;
console.log(window.v1); //undefined
다른 언어와 비교해도 별 다를 것이 없다. 다만, 초기화되지 않은 변수도 자바스크립트 엔진이 undefined로 초기화를 해줘서 에러가 나지 않게 해주는 것이 특징이다.
그렇기 때문에, 아래와 같이 작성하면 정상적으로 출력이 된다.
1
2
var v1 = 10;
console.log(window.v1); //undefined
변수 Hoisting
그런데 여기서 이상한 개념이 나온다.
hoisting이라는 단어의 뜻은 “끌어올리다” 이다.
그렇다. 자바스크립트는 변수를 끌어올린다는 뜻이다.
자바스크립트의 Hoisting : 실행 컨텍스트 안에 있는 변수들을 이 컨텍스트의 맨 위로 올려서 선언을 해주는 것
쉽게 말하면, 변수를 선언하지 않고 써도 js 엔진이 자동으로 선언을 하고 undefined로 할당해서 에러가 나지 않게 해준다는 것이다.
아래의 예시를 보자!
1
console.log(window.v1); //undefined
v1이란 변수를 선언 및 값 할당을 하지 않았음에도 정상적으로 출력된다.
이 코드는 지금 window의 v1 변수를 호출하는데, v1이 선언된 적이 없으므로 window 컨텍스트(script 자체)의 맨 위에서 변수를 선언해주고(hoisting) 호출을 해주는 것이다.
window는 자바스크립트의 기본 객체이다. 자바로 따지면 Object 클래스의 개념과 비슷한 존재이다. 그렇기 때문에, 실행 컨텍스트를 구체적으로 정해주지 않았다면 window의 변수로 선언한다는 의미이다.
즉, 아래의 코드는 에러가 난다.
1
console.log(v1); //ReferenceError
v1을 어디에 hoisting할지 도통 알 수 없기 때문이다.
Hoisting의 동작
1
2
3
console.log(window.v1); //undefined
var v1 = 10;
console.log(window.v1); //10
위의 코드는 아래의 코드와 같은 뜻이다.
1
2
3
4
var v1; //hoisting
console.log(window.v1); //undefined
v1 = 10;
console.log(window.v1); //10
이 외 예외적인 변수 선언 방식들
아래의 코드는 정상적인 코드이다.
1
2
v1 = 10; //window에 v1를 값 할당과 함께 선언
console.log(window.v1); //10
그렇다면 아래의 코드는 정상 작동할까?
1
2
v1;
console.log(window.v1);
아니다!!!
변수 이름만 딸랑 있으면 작동이 되지 않는다.
즉, var와 함께 선언을 하든지, 값을 할당하든지 둘다 하든지 해야한다는 것이다.
필자의 생각
- 코드를 처음부터 아래와 같이 작성하면 혼동이 없을 것이다.
1 2
var v1 = 10; console.log(v1);
- 다른 선언 방식을 사용한다(자바스크립트의 ES6부터 const와 let을 사용할 수 있다. 이 선언 방식이 var를 헷갈리는 우리에게 도움이 될 수 있다)
3. 그냥 타입스크립트를 사용하자