Hoisting

2020. 10. 21. 16:04Tech Article/Javascript

 

❔ Hoisting은 Javascript의 기본동작(default behavior)이기 때문에 이해가 필요하다.

 

 

 

 

Hoist의 사전적 의미(구글사전)
"
raise (something) by means of ropes and pulleys. (로프나 풀리로 어떤것을 올리는 행위)"

이런 이미지이다.


 

 

🔎 w3school 내용 : Hoisting is JavaScript's default behavior of moving all declarations to the top of the current scope (to the top of the current script or the current function). 

 

JavaScript Hoisting

JavaScript Hoisting Hoisting is JavaScript's default behavior of moving declarations to the top. JavaScript Declarations are Hoisted In JavaScript, a variable can be declared after it has been used. In other words; a variable can be used before it has been

www.w3schools.com

 

🔎 MDN 내용: JavaScript only hoists declarations, not initializations. If a variable is declared and initialized after using it, the value will be undefined.

 

Hoisting

Hoisting is a term you will not find used in any normative specification prose prior to ECMAScript® 2015 Language Specification. Hoisting was thought up as a general way of thinking about how execution contexts (specifically the creation and execution pha

developer.mozilla.org


 요약하면, variable 선언(declaration)이 되었을 때, 실행되기 전에 모든 declaration을 메모리(Lexical Environment)에 저장한다.(코드 맨 위로 끌어올리는 것과 같아 보인다. 하지만 실제로 engine이 코드 위치를 조정하는 것은 아니다.) 단 초기값(Initialization)과 할당값(Assignment)은 hoisting되지 않으므로, 값은 사용(실행)하기 전에 입력해줘야 한다.

name= 'HERE' 	// 사용하기전에 초기값 설정
console.log(name) //output : HERE
var name 		//hoisting 됨


//-------------------------------------
console.log(name) //output: undefined
var name 		//declaration은 hoisting 됨
name= 'HERE' 	//assignment는 hoisting 안됨

function도 마찬가지이다. (실행 코드 뒤에 function을 만들어줘도 무방함을 의미)

const fullName = name('stefan','cho')
console.log(fullName) //output: stefan cho

function name(first, last){
    return `${first} ${last}`
}

 

👉 function expression은 Hoist 되지 않는다.

function을 variable에 넣는 것은 값할당(Assignment)와 같기 때문에 아래 코드의 첫번째는 Hoist 되지 않는다.

// assignment혹은 initialize하는 것으로 보기 때문에, Hoist 안됨
console.log(a());
var a = function () {}; //a is used before it was defined

// function declaration은 Hoist되기 때문에 no error
console.log(a());
function a() {}; 

 

👉 let과 const은 Hoist 되지 않는다.

 let과 const의 경우 Lexical environment에 변수자체는 Hoist되지만, 결과적으로 var과 같이 undefined가 적용되지 않는다. let과 const의 경우 uninitialized가 된다. 이것을 Temporal Dead Zone이라고 부르는데 접근이 되지 않는 것이다. 

아래의 경우 let은 Hoist가 uninitialized하게 되어 reference error가 발생한다.

 

아래 3줄 코드의 순서는

line 2: let a(혹은 const a)가 hoist되고 uninitialized하게 된다. reference error를 throw한다. 

line 1: a에 "test"값을 assign을 시도하지만 값을 넣을수 없다. (접근이 안됨)

line 3: console에 출력할 수 없다.

a = "test" // a is not defined error
let a='foo' 
console.log(a) 
a = "test" // a is not defined error
const a='foo' 
console.log(a) 

 

👉 var, let, const 아무것도 사용하지 않은 경우

 javascript engine은 자동으로 variable을 declaration한다. (stackoverflow 질문보기)

a = "test" //a에 var을 쓰지 않으면 자동으로 global variable이 됨
console.log(a) // "test"

 


💡 Conclusion

Hoisting의 개념을 이해함으로써, Javascript 동작방식을 이해할 수 있다. Hoisting 동작방식 때문에, declaration(variable, function)의 경우 항상 코드 맨위에 넣을 필요는 없다.

 

 

📚 참고 자료

Hoisting in Modern JavaScript — let, const, and var

 

※ 잘못된 설명이 있는경우, 댓글로 알려주시면 찾아보고 수정하도록 하겠습니다.