JavaScript: 호이스팅(Hoisting)

MARCOIN·2022년 5월 19일
0
post-thumbnail

0. 들어가며

console.log(a) //undefined
var a = 1
console.log(a) //1

위 코드를 보면 a가 선언되기 전에 console.log() 함수를 이용하여 a를 출력했는데 에러가 발생하지 않고 'undefined'가 출력된다.

실제로 이런식으로 코딩 할 일은 없겠지만
무슨일이 일어난걸까?


1. 호이스팅이란

  • 호이스팅(Hoisting)은 'Hoist(감아올리다) + ing' 뜻처럼 함수 안에 있는 선언들을 모두 끌올해서 해당 함수의 유효 범위의 최상단에 선언하는 것을 말함.
    1) JavaScript가 컨텍스트 내부 전체를 한 번 훑으며 선언한 함수가 있을 경우 그 함수 자체, var로 선언된 변수의 식별자 등순서대로 수집함. 2) 함수 안에 존재하는 존재하는 변수/함수 선언에 대한 정보를 기억하고 있다가 실행한다.
  • 유효 범위: 함수 블록 {} 안에서 유효함

2. 호이스팅 대상

  • var로 선언된 변수의 식별자 (⚠️값은 끌어올리지 않는다.)
  • 선언한 함수 자체
  • let/const 변수 선언과 함수 표현식에서는 호이스팅이 발생하지 않음

3. var 변수의 호이스팅

console.log(a) //undefined
var a = 1
console.log(a) //1

이제서야 위에서 봤던 코드가 이해가 된다.
var a = 1로 선언된 변수가 호이스팅 되면서 a의 식별자가 JavaScript가 기억하고 있다가 (값은 가지고가지 않으므로 undefined) console.log(a)가 호출되며 undefined가 출력되는 것이다.

console.log(a) //undefined
a = 1
var a
console.log(a) //1

심지어 선언도 하지 않은 변수에 값을 할당해도 에러가 발생하지 않는걸 보면 JavaScript가 얼마나 느슨한 언어인지 알 수 있다.

for (var i = 0; i<5; i++){
    console.log(i) // 0 1 2 3 4
}
console.log(i) // 5

얼핏보면 i를 for문 밖에서 호출하는 코드가 말도 안되보이지만 정말 함수만 제외하고 나머지 var 변수를 모두 전역변수로 올려버린다. (ㄷㄷㄷㄷㄷ)

var a = 1
console.log(a) //1
var a = 2
console.log(a) //2

a 변수가 호이스팅 되므로 a를 두 번 선언해도 전혀 에러가 발생하지 않는다!
(어디까지 느슨한거지...)


4. 함수의 호이스팅

printLog() //HELLO JAVASCRIPT HOISTING
ㄹㄹㄹㄹㄹ
function printLog(){
    console.log("HELLO JAVASCRIPT HOISTING")
}

함수의 경우도 printLog()가 호이스팅 되기 때문에 함수 선언 전에 함수를 사용해도 정상적으로 출력 가능하다.

printLog() //ReferenceError: printLog is not defined

printLog = function(){
    console.log("HELLO JAVASCRIPT HOISTING")
}

단 함수표현식은 호이스팅되지 않는다.


5. 호이스팅의 우선순위 (변수vs함수)

var myName = "James"

function myName(){
    console.log("Jessica")
}

function yourName(){
    console.log("William")
}

var yourName = 'Jay'

console.log(typeof myName) //string
console.log(typeof yourName) //string

변수선언이 함수보다 먼저 끌올된다.

var myName;

function myName(){
    console.log("Jessica")
}

function yourName(){
    console.log("William")
}

var yourName = 'Jay'

console.log(typeof myName) //function
console.log(typeof yourName) //string

변수에 값이 할당되지 않은 경우 함수 선언문이 변수를 덮어쓴다.


6. 호이스팅 사용 유의사항

  • 코드의 가독성과 유지보수를 위해 호이스팅이 되도록 일어나지 않도록 한다.
  • 함수와 변수를 가급적 코드 상단부에서 선언하면, 호이스팅으로 인한 스코프 꼬임 현상을 방지할 수 있다.
  • 되도록 ES6에서 개정된 let, const를 사용한다

7. 참고 자료

https://gmlwjd9405.github.io/

자바스크립트를 배우는데 아직도 let과 var의 차이를 모른다고? : 호이스팅

profile
공부하는 기획자 👀

0개의 댓글