*잘못된 부분이 있으면 피드백 주시면 빠르게 수정하겠습니다!
ES5까지는 변수를 선언하는 방법은 var 밖에 없었습니다.
다만 변수의 유효범위를 설정하는데 어려움을 겪어서 ES6 이후 지역변수를 다루기 위해서 let, const가 등장하게 됩니다.
(var는 추가적으로 블록 스코프가 아닌 '함수 스코프' 개념을 따릅니다.)
자세한건 아래 링크를 참고하세요.
호이스팅
JavaScript에서 코드를 실행하기 전 평가와 실행 과정을 거칩니다.
그리고 변수는 위의 사진처럼 선언, 초기화, 할당이라는 3가지 단계를 거쳐 생성됩니다.
선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미합니다. 이 변수 객체는 스코프가 참조하는 대상이 됩니다.
초기화 단계(Initialization phase) : 실행 컨텍스트에 존재 하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계 입니다. 이 단계에서 할당된 메모리에는 undefined로 초기화 됩니다.
할당 단계(Assignment phase) : 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계 입니다.
모든 변수는 생성되면 위 3단계를 거쳐 생성됩니다.
그래서 자바스크립트가 실행되면 모든 변수들은 평가단계를 거치게 되는데, 호이스팅이란 모든 변수들을 끌어 모아서 각 유효범위(블록 {}안)에 최상단에 선언하는것을 말합니다.
var, let, const 모두 위 3단계를 거칩니다.
다만 var는 선언단계와 초기화 단계가 호이스팅 단계에서 동시에 실행됩니다.
그래서 아직 할당이 되지 않았는데 var로 생성된 변수를 부르게 되면 undefined를 되돌려 줍니다.
let,const는 선언은 되지만 초기화는 되지 않고, 할당이 되기 전까지 TDN(temporal dead zone)이라는 곳에 등록됩니다. 그래서 할당이 되지 않았는데 불러온다면 TDN 구간에 있는 변수들은 참조 에러(Reference Error)를 발생시키게 됩니다.
즉, 호이스팅은 모두 발생하지만 var와 let,const는 다루는 방법에 차이가 있게 되는것입니다.
다른 언어에서 흔히 쓰는 변수들은 구조적으로는 약간씩 다르겠지만 결론적으로 let, const와 동일하게 쓰인다고 이해하시면 편합니다.
참고로 함수 선언문은 위 3가지가 동시에 진행됩니다.
함수 선언식 예시
그래서 어디서 선언하든 유효 범위 (스코프) 내에서는 사용할 수 있습니다.
함수 표현식 예시
함수 표현식은 변수처럼 동작하고 호이스팅 됩니다.
따라서 var, const, let중 뭘 썼는지에 따라 호이스팅되고 변수처럼 처리됩니다.
호이스팅을 하는 이유는 현재의 실행 컨텍스트의 지금 스코프 내부에 어떤 식별자들이 있는지 탐색하고, 렉시컬 환경에 저장(기록) 해놓기 위해서 입니다.
즉.. 자바스크립트의 모든 핵심 개념이 서로 연동되있다고 볼 수 있을꺼 같은데요
자세히 알아보시려면 JavaScript deep dive란 책을 읽어보시길 추천 드립니다!
그리고 이거에 대해서 재밌는 문제가 하나 있는데요,
클로저 개념과 연동되는 문제이니 한번 생각해 보시면 좋습니다.
for(var i =0; i <100; i+=1){
setTimeout(function(){
console.log(i);
},i*1000);
}
해당 코드를 실행시키면 0, 1, 2, 3, 4가 출력되는게 아니라 100, 100, 100... 이 출력되게 되는데
원래 의도대로 고치려면 어떻게 해야할까요?
for(let i =0; i <100; i+=1){
setTimeout(function(){
console.log(i);
},i*1000);
}
해설은 다음 글을 참고하세요.
https://www.bangseongbeom.com/javascript-var-let.html
'Front-end > JavaScript' 카테고리의 다른 글
pnpm 도입기 (feat: 모노 레포) (0) | 2023.07.15 |
---|---|
자바스크립트의 async/await에 대해서 (0) | 2022.03.31 |
JS로 Single Page Application 구현 (0) | 2022.03.12 |
Generator (0) | 2022.02.02 |
[이벤트루프] 자바스크립트에서 정확한 타이머 구현? (0) | 2022.01.26 |