whatisthis?
javaScript. 호이스팅(Hoisting) 본문
지난 포스팅에서 실행 컨텍스트(Execution Context)에 대해 알아보았다.
실행 컨텍스트와 정적스코프(Lexical Scoping)을 이해하면 '호이스팅'이 무엇인지 분석할 수 있다.
Hoisting(호이스팅)
- 변수를 선언하고 초기화했을 때 선언부분이 최상단으로 끌어올려지는 현상.
- 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것.
자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
함수 내부의 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
실제 메모리에서는 변화가 없다.
console.log(zero); // 에러가 아니라 undefined
sayWow(); // 정상적으로 wow
function sayWow() { // 함수 선언부 - 최상단으로 끌어올려짐
console.log('wow');
}
var zero = 'zero'; // 변수 선언부- 최상단으로 끌어올려짐
위 예제는 선언보다 호출을 먼저 하기 때문에 (1,2번째 줄) 에러가 발생할 것 같지만
에러 없이 정상 작동함.
>> 변수선언 (마지막줄)과 함수선언(세번째줄)이 최상단으로 끌어올려졌기 때문.
function sayWow() {
console.log('wow');
}
var zero;
console.log(zero); // undefined - 값 할당이 안되어있기 때문
sayWow();
zero = 'zero';
함수선언 -> 변수선언 -> 변수호출 ->함수호출 -> 변수 값 할당
RESULT : undefined , 'wow'
❕ 함수표현식으로 선언한 경우에는 에러발생! (var 함수명 = function() 형식)
sayWow(); // (3)
sayYeah(); // (5) 여기서 대입되기 전에 호출해서 에러
var sayYeah = function() { // (1) 선언 (6) 대입
console.log('yeah');
}
function sayWow() { // (2) 선언과 동시에 초기화(호이스팅)
console.log('wow'); // (4)
}
* sayWow함수의 경우 선언과 동시에 초기화하기 때문에
선언 전에 호출을 해도 호이스팅에 의해 제대로 실행된다.
** sayYeah함수의 경우에는 선언만 하고 대입은 하지 않았다.
즉, 대입되기 전에 둘째줄에서 먼저 호출해버려서 에러가 발생한다.
>> 처음 실행시 전역 컨텍스트가 먼저 생성됨.
sayWow함수는 함수 선언식이므로 컨텍스트 생성 후 바로 대입됨.(호이스팅가능)
sayYeah함수는 대입되기 전에 호출해서 에러가 발생.
'전역 컨텍스트': {
변수객체: {
arguments: null,
variable: [{ sayWow: Function }, 'sayYeah'],
},
scopeChain: ['전역 변수객체'],
this: window,
}
- 전역 컨텍스트의 variable은 대입되지 않음.
- 즉, sayYeah는 함수로 인식하지 않고, 변수로 인식하는 것임.
>> 함수와 변수를 가급적 코드 상단부에서 선언해야 호이스팅으로 인한 스코프 꼬임 현상 방지 가능.
자바스크립트 함수표현식에 대한 내용은 MDN 문서를 참고.
var myFunction = function [name]([param1[, param2[, ..., paramN]]]) { statements };
함수선언식(function문) | 지정된 파라미터를 갖는 함수를 정의함. 끌어올려짐. (호이스팅 가능) function functionName() { console.log("Can Hoisting"); } |
함수표현식(function expression) | 호이스팅 불가. 에러발생. 🟨 클로저로 사용하거나 콜백으로 사용할 수 있다. var functionName = function() { console.name("Can NOT Hoisting"); } |
+) 함수표현식 vs 함수선언식에 대한 추가 포스팅
REFERENCE
https://www.zerocho.com/category/JavaScript/post/5741d96d094da4986bc950a0
이 포스팅은 zerocho님의 javascript 강의를 보고 작성한 글입니다.
공부+기록 용으로 작성한 것이며, 자세한 것은 위 포스팅을 참고하세요!
'WEB STUDY > JAVASCRIPT' 카테고리의 다른 글
javaScript. 호출 스택 (0) | 2022.01.11 |
---|---|
javaScript. 클로저(Closure) (1) | 2022.01.11 |
javaScript. 함수선언식 vs. 함수표현식 (0) | 2022.01.11 |
javaScript. 실행 컨텍스트 (Execution Context) (0) | 2022.01.11 |
javaScript. IIFE(즉시 호출 함수 표현식) (0) | 2022.01.11 |