Tech Blog of Pinomaker
Published 2022. 9. 1. 14:31
[JavaScript] Hoisting F.E/JavaScript

Hoisting

Hoisting이란 변수의 선언만을 해당 스코프의 맨 위로 끌어올리는 것을 의미한다. 아래의 예시를 보고 이해해보자.

 

아래의 1번을 보면, x는 console.log아래에서 선언과 초기화가 이루어져있는 데도, Error가 아닌 undefiend가 나오고 있다. 이것이 Hoistring의 예시라고 생각하면 된다. 

 

1번처럼 작성한 코드가 Hoistring으로 2번처럼 아래에서 선언된 변수가 선언만은 위에서 되어 undefined가 나오는 것이다.

// 1번
console.log(x) // undefiend
var x = 1

// 2번
var x
console.log(x)
x = 1

 

그렇다면 Hoisting이 안 된다면 어떻게 될까 아래의 예시를 보면 Hoisting이 되지 않는다면 ReferenceError가 나오는 것을 볼 수 있다.

console.log(x) // ReferenceError
x = 1

 

그렇다면 함수는 어떻게 될까?

 

함수도 마찬가지로 Hoisting이 되지만 뭔가 var와는 다른 걸 볼 수 있다 undefined가 나오지 않는 것을 볼 수 있는 데, 이는 함수는 변수와 다르기 때문에 함수는 초기화가 없고 선언 밖에 없어서 Hoisting이 되면 undefined가 나오진 않는다.

// 1번
console.log(foo()) // foo
function foo(){
    return "foo"
}

// 2번
function foo(){
    return "foo"
}

console.log(foo()) // foo

 

binding

코드의 어떤 식별자가 실제로 어떤 값을 가르키는 지 결정하는 것을 bining이라고 하며, JavaScript는 binding을 lexical scope를 통해서 하게 되는데, lexical scope란 안 쪽에서는 바깥 쪽 변수에 접근 할 수는 있지만 반대의 경우는 안 되는 것이다.

 

예를 들어보자 아래의 코드 1번을 보면, 안 쪽의 x를 바깥 쪽의 x를 binding 하지 못 해서 ReferenceError가 나온 것을 볼 수 있지만 2번 코드를 보면 안 쪽에선 바깥 쪽의 x를 binding 할 수 있기에, Hello를 출력한 것을 볼 수 있다.

// 1번
const foo = () => {
  var x = "Hello"
  console.log(x) // Hello
}

console.log(x) // ReferenceError

// 2번
var x = "Hello"
const foo = () => {
  console.log(x) // Hello
}

 

var는 block scoping의 대상이 아니라 아래와 같이 코드도 작성이 가능하지만 let, const는 아래와 같이 하면 두 개의 선언으로 인식 되어 Error가 난다.

var x = 1
if(true) var x = 2
console.log(x) // 2

// let, const는 block scoping를 받아 위와 같이 할 수 없다.
profile

Tech Blog of Pinomaker

@pinomaker

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!