«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

방춘덕(고양이 키우면 지을 이름)의 개발 블로그입니다.

hoisting 본문

JS

hoisting

방춘덕 2019. 12. 7. 01:59

이 내용은 이전에 작성했던 execution context와 execution context stackexecution context의 생성과정 글과 관련이 있습니다.


Hoisting is JavaScript's default behavior of moving declarations to the top.

(hoisting은 선언을 맨 위로 이동시키는 JS의 기본 동작이다.)

- https://www.w3schools.com/js/js_hoisting.asp

1). JS의 선언과 hoisted


먼저 예제를 보고 시작해보자.

console.log(hello) // undefined
var hello = 'HI!'

 

왜 다른 언어들과 같이 error를 출력하지 않고 undefined로 출력될까? execution context와 내용에서 다룬 것과 같이, JS에서는 코드를 직접적으로 실행하기 전에 코드를 읽으며 모든 선언들 (변수, 함수 등)을 메모리에 기록하여 값을 미리 undefined로 정의해놓기 때문이다.

 

var hello
console.log(hello)
hello = 'HI!'

위와 같이 변환된다고 개념적으로 이해하면 된다. 여기서 헷갈리지 않아야 할 점은 위와 같이 물리적으로 (즉, 코드에서) 최상단으로 이동하는 것이 아닌, 실제 코드에서 작성한 바로 그 위치에서 메모리에 올라간다.

 

그럼 hello 변수에 언제 "HI!"란 값을 저장할까? 바로 코드를 실행시키며 var hello = 'HI!'를 지나갈 때이다. JS에서는 코드를 실행시키며 값을 대입하므로 그 이전까지의 선언은 variable environment에 undefined로 저장된다.

2). JS의 초기화는 hoisting이 아니다.


JS는 선언만 hoisting 할 뿐, 초기화에서는 그렇지 않다. 아래의 예제를 보자

var a = 10
var b = 20
console.log('a:', a, 'b:', b) // a: 10 b: 20

 

var a = 10
console.log('a:', a, 'b:', b) // a: 10 b: undefined
var b = 20

 

왜 두 코드의 결과 값의 차이가 날까? 그 이유는 누누이 언급했듯 hoisting은 선언만 상단으로 올리고 초기화는 해당 라인을 실행할 때 이루어 지기 때문이다.

 

var a = 10
var b
console.log('a:', a, 'b:', b) // a: 10 b: undefined
b = 20

따라서 개념적으로는 위와 같이 이루어진다.

3). 함수에는 어떨까?


이제 변수에 관련해서 hoisting이 어떤 의미인지는 이해했으니, 함수 선언과 관련해서 알아보자. 사실 크게 다를 것도 없다.

futureCatName('왕춘식') // 내 미래 고양이 이름은 왕춘식이다.

function futureCatName(name) {
  console.log(`내 미래 고양이 이름은 ${name}이다.`)
}
function futureCatName(name) {
  console.log(`내 미래 고양이 이름은 ${name}이다.`)
}

futureCatName('왕춘식') // 내 미래 고양이 이름은 왕춘식이다.

위 코드들 또한 함수의 선언부(구현부 제외)가 hoisting에 의해 미리 상단에 선언되어 이미 상단에 선언되어 있고, 이후 execution phase에서 코드를 실행시키기 때문에 정상적으로 실행된다.

 

그렇다면 매개변수는 왜 잘 넘어갈까? 이 부분 또한 이전 글을 읽었다면 이해가 쉬웠을 수도 있다. JS에서 변수는 이전 execution context의 variable object를 참조하기 때문에 이미 futureCatName 함수의 execution context creation phase에서부터 name에 "왕춘식"이란 값이 대입돼 있기 때문이다.

위 코드의 execution context의 실행 과정을 보인 모습

 

4). 선언이 중복된다면 어떨까?


hoisiting은 선언을 상단으로 옮긴다. 하지만 선언들이 중복일 땐 어떻게 될까?

function A() {
  console.log('A1')
}
  
A() // A2
  
function A() {
  console.log('A2')
}

이 코드는 아래와 같이 개념적으로 표현된다. (다시 한번 강조하지만 절대 물리적으로 이렇지 않다. 이해하기 쉽게 표현하기 위한 것이다.)

 

var A
A = function () {
  console.log('A1')
}
  
A = function () {
  console.log('A2')
}
  
A() // A2

함수 식별자가 겹칠 경우, 가장 아래의 함수 선언부가 연결되므로 결국은 "B2"가 출력된다.

 

var A = function () {
  console.log('A1')
}

A() // A1

var A = function () {
  console.log('A2')
}

그렇다면 이 코드는 왜 "A1"이라는 결과를 출력할까? 다시 한번 개념적으로 표현한 코드를 봐보자.

var A

A = function () {
  console.log('A1')
}

A()

A = function () {
  console.log('A2')
}

변수를 함수로 초기화한다고 기존 변수일 때 hoisting 규칙이 사라지는 것은 아니다. 따라서 A1의 함수가 execution phase에서 더 먼저 초기화가 됐으므로 A1이 출력됨이 타당하다.

 

var A = function () {
  console.log('A1')
}

A() // A1

var A = function () {
  console.log('A2')
}

A() // A2

따라서 코드를 이렇게 변경하면 "A1", "A2" 모든 결과를 볼 수 있다.

이 글을 작성할 때 읽은 감사한 자료들.


http://chanlee.github.io/2013/12/10/javascript-variable-scope-and-hoisting/

 

자바스크립트의 변수범위와 호이스팅

이 글에서, 우리는 자바스크립트 변수의 범위(scope)와 호이스팅(hoisting), 그리고 이 두가지의 특징에 관해 배워보겠습니다. 자바스크립트의 변수범위와 호이스팅이 작동하는 원리를 이해하는것은 필수적입니다. 이 두가지 컨셉은 직관적이면서도 이해하기가 쉽지 않습니다. 거기에는 미묘한 차이가 있으며, 자바스크립트 프로젝트에서 성공하기 위해서는 반드시

chanlee.github.io

https://www.w3schools.com/js/js_hoisting.asp

 

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

https://developer.mozilla.org/ko/docs/Glossary/Hoisting

 

Hoisting

호이스팅(hoisting)은 ECMAScript® 2015 언어 명세 및 그 이전 표준 명세에서 사용된 적이 없는 용어입니다. 호이스팅은 JavaScript에서 실행 콘텍스트(특히 생성 및 실행 단계)가 어떻게 동작하는가에 대한 일반적인 생각으로 여겨집니다. 하지만 호이스팅은 오해로 이어질 수 있습니다.

developer.mozilla.org

https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-what-is-hoisting-i n-javascript-a63c1b2267a1

 

What is Hoisting in JavaScript?

Find out what hoisting in JavaScript means, with examples of code to help explain it all.

medium.com

http://insanehong.kr/post/javascript-function/

 

Function Declarations(함수선언) vs Function Expressions(함수표현) | Insanehong's Incorrect Note

소개 이번 글은 function이란 주제를 다뤄볼가 한다. javascript에서 function 은 매우 중요한 녀석이다. 특히 객체를 다루면서 이 function은 절대 빠질수도 빠져서도 안되며 이에 대한 이해가 없다면 javascript 객체에 대한 이해를 제대로 하지 못할 것이다. 그런 이유로 이 글은 Object에 대해 다루기전에 다뤘다면 더 좋았을 거라 생각하지만 사실 자바스크립트에는 연관된 내용이 너무 많은 탓이라며 스스로를 위로하고 있다.

insanehong.kr

 

'JS' 카테고리의 다른 글

prototype과 prototype chain  (0) 2019.12.16
scope  (1) 2019.12.13
event loop  (0) 2019.12.11
execution context의 생성과정  (0) 2019.12.05
execution context 와 execution context stack  (0) 2019.12.02