본문 바로가기
JAVASCRIPT & TYPESCRIPT

Javascript 호이스팅(hoisting)과 변수(let, var, const)

by ™ℬℑ 2022. 6. 2.

변수(variable)

변수의 생성 과정은 3단계로 이루어져 있다. 

1. 선언 단계

2. 초기화 단계

3. 할당 단계

 

var는 선언과 초기화가 동시에 된다.

그래서 할당 전에 호출하면 에러를 내지 않고 Undefined가 나온다. 밑에 예시들을 보며 설명하겠다.

 

var는 한번 선언된 변수를 다시 선언할 수 있다.

var name = 'shyun';

console.log(name);   > shyun

 

var name = 'Jane';

console.log(name);  > Jane 

 

var name = shyun이라고 선언했지만, 후에 다시 var를 사용하여 똑같은 변수명으로 다른 값을 선언할 수 있다.

 

var는 선언하기 전에 사용할 수 있다. (var는 선언과 초기화가 동시에 된다.)

 

console.log(name);

var name = 'shyun';   

 

var로 선언한 모든 변수는 코드가 실제로 이동하지 않지만, (호이스팅) 코드가 최상위로 올라간 것처럼 동작합니다.

하지만 선언은 호이스팅되지만 할당은 호이스팅 되지 않는다. 그래서 console.log(name)의 값은 Undefined이 된다. 이 말에 의미는 name이라는 변수는 console.log(name); 보다 밑에 선언되었지만, 에러가 나지 않는다.

이유는 변수는 선언된 것과 같이 호이스팅되었지만, 변수의 값은 호이스팅되지 않는다. 

 

 

● let은 선언 단계와 초기화 단계가 분리되어 진행된다.

 

let은 선언하기 전에 사용할 수 없다.

 

console.log(name);

let name = 'shyun';   

 

위에 var 변수와 같은 상황이지만 let으로 선언했을 때 곧 바로 레퍼런스 에러를 불러온다. 그렇다고 let 호이스팅 안 되는게 아니다. 호이스팅을 쉽게 설명하며 스코프 내부 어디에서든 변수 선언은 최상위에 선언된 것처럼 행동하는 것이다.

또 한 호이스팅은 스코프 단위로 일어난다. 

let은 호이스팅 되는데 왜 레퍼런스 에러를 불러오는 걸까? 

 

그 이유는 let은 선언단계와 초기화 단계가 분리되어 일어나기 때문이다. 호이스팅되면서 선언단계가 이루어지지만 초기화 단계는 실제코드에 도달했을 때 이루어지기 때문에 레퍼런스 에러가 난다.

TDZ를 이해하면 좀 더 이해하기 쉽다. Temporal Dead Zone (할당을 하기전에는 사용을 할 수 없다. 이는 코드를 예측하게 하고 잠재적인 버그를 불러일으키기 때문이다.)

let도 const와 함께 TDZ에 영향을 받는다.

 

console.log(name);   > TDZ 

let name = 'shyun';    > 함수 선언과 할당

console.log(name);   > 함수 출력

 

 

const는 선언과 할당 초기화를 동시에 이루어진다.

 

아래 예시를 보면 이해하기 쉽다.

 

let name; 

name = 'shyun';

 

var name;

name = 'shyun';

 

이 두 코드는 모두 문제가 없다. 선언과 할당이 동시에 이루어지지 않기 때문이다.

하지만 const는 선언과 할당 동시에 이루어진다.

 

const name;

name = 'shyun';

 

위와 같이 varlet처럼 작성하면 에러가 발생한다. 

const name = 'shyun'; 이렇게 선언과 할당이 동시에 이루어져야 한다.

 

스코프

 

var 함수 스코프이다. var =(function-scopped)

 

let, const는 블록 스코프이다. let,const = (block-scopped)

 

블록 스코프는 모든 코드 블록에서 선언된 변수는 코드 블럭 내에서만 유효하며 외부에서는 접근할 수 없다. 즉 코드 블럭 내에서 선언한 변수는 지역변수인 셈이다. 

코드 블럭 Ex) 함수, if 문, for 문, while 문, try/catch 문

 

함수 스코프는 함수 내에서 선언된 변수만 그 지역변수가 된다. 예를 들어

 

if (age>20) {

     var txt='adult';

}

console.log(txt);         > 'adult'

 

이렇게 if문 밖에서도 console.log(txt); 출력되고 사용될 수 있다. 하지만 let, const는 저렇게 사용할 수 없다.

중괄호{} 안에서만 사용할 수 있다. 

 

함수 스코프 중에서도 유일하게 벗어날 수 없는 블록이 있다. 바로 function이다.

function cal(num1, num2) {

 var result = num1+ num2;

}

 console.log(result);  > err result is not defined 라는 에러를 가지고 온다. 이렇듯이 아무리 함수 스코프라도 유일하게 function내부에 선언된 변수를 외부에서 사용할 수 없다.

 

글을 마치며

TDZ와 호이스팅 그리고 스코프에 대해서 조금이나마 공부한다면 왜 var로 된 변수를 사용하지 않는지 알 수 있다.

es6부터 letconst는 Javascript를 좀 더 엄격하게 만드는데 사용되고 있다. 너무 깊게 공부하지 않더라도 꼭 한번

TDZ, 호이스팅, 스코프에 관하여 공부한다면 변수를 이해하는데 그리고 어떤 식으로 변수가 행동하는지를 알 수 있게 된다. 

 

댓글