always declare your variables at the top
아래 코드를 실행하면 콘솔에 어떤 값이 출력될까?
1| var text = 'outside';
2| function logIt() {
3| console.log(text);
4| var text = 'inside';
5| };
6|
7| logIt();
전역 변수를 먼저 바라봐서 outside라고 답할 수 있다.
하지만 틀렸다.
함수 지역 변수의 호이스팅이 일어나서 inside가 출력된다고 답할 수 있다.
이 답도 틀렸다.
그렇다고 에러를 던지는 코드도 아니다.
콘솔에는 undefined가 출력된다.
이 문제를 이해하기 위해서는, 자바스크립트의 몇 가지 특성을 설명할 수 있어야 한다.
자바스크립트에서 함수는 자체 스코프를 형성한다.
1| function setVar(){
2| var varInFunction = 'inside a function';
3| }
4|
5| setVar();
6| console.log(varInFunction); // throws 'ReferenceError: varInFunction is not defined'
자바스크립트 함수 내부에 선언된 변수는 함수 외부에서 접근할 수 없다.
(하지만 if문이나 for loop문과 같은 블록 함수에서는 새로운 스코프를 형성하지 않는다.)
변수 선언이란 간단히 인터프린트에 변수가 존재한다고 알리는 역할만 한다.
기본적으로 변수는 undefined가 할당된다.
1| var unicorn;
2| console.log(unicorn); // logs undefined (NOT a ReferenceError)
변수는 선언한 이후에 할당하거나
1| unicorn = 'Sparkles McGiggleton';
선언과 동시에 할당할 수 있다.
1| var centaur = 'Horsey McPersonhead';
자바스크립트에서 변수 선언은 hoisted 된다. 호이스팅은 현재 스코프의 가장 위에 변수가 선언된다는 것을 뜻한다.
하지만 할당은 일어나지 않는다.
원래 문제로 돌아가 보자.
1| var text = 'outside';
2| function logIt() {
3| console.log(text);
4| var text = 'inside';
5| };
6|
7| logIt();
text란 변수는 logIt() 함수 가장 위에 선언된다. (하지만 할당되지는 않았다.)
이는 인터프린터가 우리 코드를 아래와 같이 바꿨다는 것이다.
1| var text = 'outside';
2| function logIt() {
3| var text;
4| console.log(text);
5| text = 'inside';
6| };
7|
8| logIt();
그래서 이 코드는 선언만 된 변수인 text, undefined라는 값을 출력한다.
자바스크립트에서 변수를 선언할 때, 해당 변수가 호이스팅이 일어나서 top 레벨 스코프에 선언된다는 것을 알아야 한다. 호이스팅은 위에서 봤던 것처럼 예측하지 못한 버그를 낼 수 있다.
가장 좋은 방법은 호이스팅을 예측하지 말고 변수 할당을 항상 스코프 맨 위에서 하는 것이다.
출처: