whatisthis?

javaScript. 호이스팅(Hoisting) 본문

WEB STUDY/JAVASCRIPT

javaScript. 호이스팅(Hoisting)

thisisyjin 2022. 1. 11. 12:55

 

 

javaScript. 실행 컨텍스트 (Execution Context)

실행 컨텍스트 (Execution Context) 실행 컨텍스트(Execution Context)는 scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리이다. var name = 'zero'; // 전역변수..

mywebproject.tistory.com

 

지난 포스팅에서 실행 컨텍스트(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 문서를 참고.

 

함수 표현식 - JavaScript | MDN

function 키워드는 어떤 표현식(expression) 내에서 함수를 정의하는 데 사용될 수 있습니다.

developer.mozilla.org

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 함수선언식에 대한 추가 포스팅

 

 

 

javaScript. 함수선언식 vs. 함수표현식

 

mywebproject.tistory.com

 

 

 

 


REFERENCE

https://www.zerocho.com/category/JavaScript/post/5741d96d094da4986bc950a0

 

(JavaScript) 실행 컨텍스트 - 클로저와 호이스팅

안녕하세요. 이번 시간에는 범위에 이어 실행 컨텍스트와 클로저에 대해서 살펴보겠습니다. 제가 지난 시간에 실행 컨텍스트가 제일 중요하다고 하면서 강좌를 마쳤습니다. lexical scoping과 이것

www.zerocho.com

이 포스팅은 zerocho님의 javascript 강의를 보고 작성한 글입니다.

공부+기록 용으로 작성한 것이며, 자세한 것은 위 포스팅을 참고하세요!