호이스팅이 뭘까요? hoisting은 '밧줄 등으로 끌어올리다'라는 의미를 갖고 있습니다.
JavaScript에서 뭘 끌어올린다는 것일까요?
예를 들어, 다음과 같은 함수가 있다고 해봅시다.
foo();
function foo() {
console.log('a');
}
C++에서는 한줄한줄 읽기 때문에 미리 정의되어있지 않으면 컴파일 에러가 뜹니다. 그런데 위의 코드는 JS에서 정상적으로 작동합니다. 이는 JS에서 선언들을 모두 미리 정의해주기 때문입니다. 할당은 나중에 하구요.
함수의 선언부가 위로 끌어올려진듯하게 보이죠. 이것을 호이스팅이라고 부릅니다.
JS는 실행 컨텍스에 변수나 함수가 생길 자리를 미리 마련해둡니다. 이 과정은 컴파일 타임에 실행되는 것이구요.
함수뿐만 아니라 변수도 마찬가지로 호이스팅이 됩니다.
여기서 var, let, const같은 변수 선언 방식과 호이스팅은 무슨 관련이 있을까요?
var는 ES5까지 쓰이는 변수 선언 방식이었습니다. 이 var가 호이스팅될 때는 값이 undefined로 초기화됩니다.
var x = 0;
var foo = function() {
console.log(x); // undefined
var x = 1;
}
foo();
위 코드는 undefined를 콘솔에 출력합니다. 엥...?
그 이유는 foo가 선언됨과 동시에 foo내에서 x가 호이스팅이 되어 undefined가 되기 때문입니다. 밖에 있는 var x = 0은 확인하지 않습니다. 그렇다면 단순 수가 아니라 함수를 할당한다면?
var foo = function() {
console.log(fn());
var fn = function(){
return "a";
}
}
foo();
저 스코프 내에서 fn은 undefined로 먼저 초기화되기 때문에 콘솔로그에 출력되기 전, fn is not a function 에러가 뜹니다. undefined는 함수가 아니기 때문이죠!
그런데 undefined는 JS 코딩에서 자주쓰는 값입니다. 또, 위의 예시와 같은 상황이 자주 발생할텐데 매번 이런걸 생각해야한다니.. 상당히 불편하네요. 그래서 let, const가 추가된 ES6부터는 요런 문제들이 해결됩니다.
let과 const
let과 const는 호이스팅 시 초기화되지 않습니다.
let foo = function() {
console.log(fn());
let fn = function(){
return "a";
}
}
foo();
위의 코드는 Reference Error를 띄웁니다. 호이스팅 자체는 일어납니다. 하지만, 콘솔로그를 찍으려는데 fn()은 선언만 해놓고 초기화가 안된 상태죠. 그래서 Reference Error를 띄우게 됩니다. "아직 선언 안된 건 쓸 수 없어요!"라고 메시지도 띄우죠. var처럼 타입 에러를 띄우지 않습니다. 이는 디버깅할때 상당히 도움이 될 것입니다.
const도 마찬가지입니다. 둘의 차이는 지난 포스트 참고!
따라서 ES6 이후 버전을 쓰신다면 var보다는 let, const를 쓰시기 바랍니다.
Reference
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
'Me > FrontEnd' 카테고리의 다른 글
[JavaScript] Promise와 async/await (0) | 2022.05.16 |
---|---|
프로젝트 중 CORS 에러 수난기 (0) | 2022.05.14 |
[JavaScript] const, let, var의 차이점 (0) | 2022.05.05 |
[JavaScript] 콜백함수(Callback function)과 비동기처리 (0) | 2022.04.30 |
SCSS에서 변수 사용하기 (0) | 2022.04.24 |
댓글