변수/함수 선언이 스코프의 최상단에 끌어올려진것.
console.log(a) // undefined 값이 뜨게된다.
var a = "a";
코드의 실행순서는 아래에서 밑으로 흐른다.
그럼위의 코드를 봤을때 에러가 나야 정상인 상황에서 코드를 실행시켜보면 undefined 값이 뜨게된다.
그이유는 자바스크립트 엔진이 코드를 실행하기 전에 실행컨텍스트를 위한 과정에서 모든 선언((예)var a)을 스코프의 최상단으로 끌어올리기 때문이다.
스코프란?
번역하면 범위 이고 변수에 접근할수 있는 범위를 뜻함
var a=1;
var outer = function (){
var inner = function(){
console.log("inner",a);
var a = 10;
};
var a=4;
inner();
console.log("outer",a);
};
outer();
console.log("전역",a);
내가 이코드를 처음 실행해봤을때 내가 예상한 값은
inner 1
outer 4
전역 1
이러한 값이 나올거라 예상했는데 실제로는
inner undefined
outer 4
전역 1
이러한 값이 나왔고 이해를 할수 없었는데 그이유는 전역변수인 a에 값이 할당되어 있고 그값은 전역 > outer > inner 에서 모두 쓸수 있는 값이기 때문이였다.
그런데 호이스팅을 통해 각스코프의 실제 코드를 보자면
var a=1;
var outer = function (){
var a;
var inner = function(){
var a;
console.log("inner",a);
a = 10;
};
a=4;
inner();
console.log("outer",a);
};
outer();
console.log("전역",a);
이러한 상태로 코드를 실행한다. 호이스팅 과정에서 변수 a를 inner 스코프의 최상단으로 끌어올리고 console 보다 값을 늦게 할당해서 처름 찍히는 콘솔은 undefined 값이 나오게 되는것이다.
여기서 더 나아가자면 변수 선언 방식에 있어서도 다른 결과를 나타내는데 일단 차이점을 보자면
var
1. 선언과 초기화 과정이 같이 일어나게 되며 초기화 과정에서 메모리값을 할당받기 때문에 선언과 동시에 값에 undefined 가 저장됨 그래서 위에서 본 예제에서 변수 a에 할당한 값이 없더라도 에러가 나지않음
2. 재선언, 재할당 가능
3. Function-scoped
let
1. 선언과 초기화 과정이 거의 동시에 일어나지만 단계가 두단계로 나뉘어짐, 선언만 했을시에 초기화가 되지 않고 메모리값을 할당받지않아 객체를 사용할 경우 그 객체의 변수가 참조하고 있는 메모리값이 없어서 에러발생
2. 재할당 가능, 재선언시 에러발생
3. Block-scoped
const
1. 선언과 초기화, 할당까지 한번에 해줘야하며
상수(변하지않는수)값을 할당해줘야함 재할당을 할경우 에러발생
2. 재선언, 재할당 불가능
3. Block-scoped
위의 예제를 inner 스코프안의 변수 선언방식을 var, let, const로 바꿔가며 실행결과를 알아보겠다.
var
let or const 동일
let, const 의 경우초기화 즉 메모리할당을 받지 못한상태에서 사용해서 에러가나는걸 확인할수 있다.
var 같은경우 재선언이 가능하기에 전역에서 재선언을 할경우 먼저 선언한 변수의 값까지 변하게 되고 선언만 하고 사용했을때도 에러가 나지않아 ES6이후로 let과 const를 쓰라고 권장되어지고 있다.
console.log(a())
console.log(b())
//함수 선언식
function a(){
return "함수선언식"
}
//함수 표현식
var b = function(){
return "함수 표현식"
}
함수 선언식과 표현식의 작성방법은 위와 같고 위의 코드를 실행전 호이스팅이 된 실제 실행순서는 아래와 같다.
//함수 선언식
function a(){
return "함수선언식"
}
var b;
console.log(a())
console.log(b())
//함수 표현식
b = function(){
return "함수 표현식"
}
그래서 실제 콘솔에 찍힌 값은
"함수선언식"
undefined
순으로 출력하게 된다.
이상 호이스팅 포스팅을 마치겠습니다. 감사합니다.
함수 선언문 - 함수자체가 호이스팅 || 함수 표현식 - 변수가 호이스팅
TDZ (temporal dead zone) 공부 하고 있는데 여전히 어렵네요 !
블로깅 정리 잘 되어있네요 감사합니다~