Hoisting
은 단어 그 자체로 끌어올린다는 의미를 가지고 있다
hoisting
에 있어서 중요한 것은 함수 표현식인지 함수 선언식인지 여부의 차이가 아닐까싶다.
함수 선언식은 함수 선언을 끌어올리고 함수 표현식은 변수 선언을 끌어올린다.
아래의 코드로 hoisting
이 어떻게 일어나는지 알아보자. 그리고 결과값은 어떻게 나올까?
console.log(a());
console.log(b());
console.log(c());
function a() {
return 'a';
}
var b = function bb() {
return 'bb';
}
var c = function() {
return 'c';
}
위와 같은 코드가 실제로는 아래처럼 함수 및 변수가 호이스팅되어 동작된다는 것이다.
function a() {
return 'a';
}
var b;
var c;
console.log(a());
console.log(b());
console.log(c());
b = function bb() {
return 'bb';
}
c = function() {
return 'c';
}
a
는 함수 선언식이기 때문에 함수 자체가 hoisting
되었고, b,c
는 표현식이기 때문에 변수가 hoisting
되었다.
그래서 결과값은
// a
// b is not function
그리고 c는 console.log(b())
에서 오류가 났기 때문에 실행되지 않는다.
function book(){
function getBook(){
return "책1";
}
console.log(getBook());
function getBook(){
return "책2";
}
};
book();
위 같이 같은 함수명일 경우는 어떻게 될까?
hoisting
을 모를땐 아래에 선언된 getBook 함수가 console.log 보다 아래에 있으니까 당연히 "책1"이 출력될꺼라고 생각했다. 하지만 그것은 나의 착각이었다.
이것의 순서는 아래와 같다.
1. book() 함수 호출
2. 2번째 줄 getBook() 함수가 hoisting 됨
3. 아래의 getBook() 함수가 hoisting되면서 기존에 선언된 getBook 함수를 덮어씀
4. console.log로 출력시 "책2" 출력
5. book 함수의 return 값이 없으므로 undefined 출력
호이스팅을 모르면 정말 햇갈릴만 하다.
{
book: "책2"
}
위 같은 경우는 단순히 보면 book이라는 key
에 return에 있는 value
를 덮어씌우는 개념이라고 보면 될것 같다. 그리고 위에서 변수 선언을 할 때, var
키워드를 사용하였는데, 지금은 ES6로 올라가면서 let
const
를 사용함에 따라 var
키워드를 사용할 때처럼 hoisting
으로 인한 문제는 생기지 않는다. 하지만 let
과 const
도 hoisting
이 되지 않는것은 아니다.
호이스팅이 상당히 복잡해서 실제 JS 엔진 구동 따라서 다시 한 번 정리해봐야겠어요.