[TIL 1] 호이스팅(hoisting)

nyoung·2022년 3월 21일
0

자바스크립트

목록 보기
1/11
post-thumbnail

변수 호이스팅

console.log(a);
var a;

이 코드를 보고, 처음엔 당연히 에러가 나겠지 하고 생각했지만 아니었다!
자바스크립트에는 "호이스팅"이라는 특징이 있는데, 이 때문에 코드가 동작한다.

실행 결과는?
=> undefined

자바스크립트를 배우면서 기존에 배웠던 언어들과 참 다르다는 것을 새삼 느낀다. 신기방기🤔

그렇다면 호이스팅이란 무엇일까?

식별자 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 것!

자바스크립트에서는 변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이전단계에서 먼저 실행된다.
소스코드를 실행하기 위한 준비 단계인 평가 과정에서, 자바스크립트 엔진은 먼저 변수 선언을 포함한 모든 선언문을 소스코드에서 먼저 선언하고, 그 다음 나머지 소스코드를 한 줄씩 순차적으로 실행한다.

변수 선언 뿐 아니라, var, let, const, function, class 키워드를 사용해 선언하는 모든 식별자(변수, 함수, 클래스 등)은 호이스팅 된다.

선언 후 값의 할당은?

선언문은 호이스팅되지만 값의 할당은 소스코드를 실행하는 시점, 런타임에 이루어진다.
따라서,

console.log(a);
var a = 1;
console.log(a);

가 있을 때, 결과는
undefined
1
이 된다.

근데 왜 호이스팅이 발생하는건가요..?

다른 언어들과 비교했을 때 굉장히 특이하다고 생각해서 왜 이러는건지 궁금했다. 왜 굳이..?
이런 생각이 들었달까..?

찾아보니 자바스크립트 엔진의 동작 원리 때문이라고 한다.

자바스크립트 엔진은 소스코드를 평가 - 실행하는 2단계로 나누어 진행된다.
평가 과정에서 변수와 함수 식별자를 key로 해 실행 컨텍스트가 관리하는 환경에 등록하고 이 과정에서 value 값을 undefined로 초기화 해준다.
따라서 코드를 실행할 때는 이미 함수 선언문과 변수가 생성되어 있는 상태이기 때문에 어디서든 함수나 변수를 호출할 수 있는 것이다!

어떠한 장점이 있다기 보다는 자바스크립트의 특성, 동작 원리라고 생각하면 될 것 같다..😊

호이스팅 때문에 실수할 것 같은데..

사실 이러한 호이스팅 때문에 실수할 여지가 늘어나기 때문에, var 보다는 es6에서 만들어진 let, const를 사용하기를 권장하고 있다.

let은 var과 같이 호이스팅 되지만, 선언문 위에 사용되면 에러가 난다!

변수를 선언할 때 let을 쓰면 참조 에러가 발생한다.

위에 써있듯이, var 키워드로 선언한 변수는 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계초기화 단계한번에 진행된다.

하지만 let 키워드로 선언한 변수는 선언 단계초기화단계분리되어 진행된다. 즉 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계가 먼저 실행되지만 초기화 단계는 변수 선언문에 도달했을 때 실행된다.

따라서 초기화 단계가 실행되기 이전에 변수에 접근하려고 하면 참조에러(Reference Error)가 나는 것이다! 스코프의 시작 지점 부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 일차적 사각지대 라고 부른다고 한다.🤓

console.log(a); // 참조 에러
let a;
console.log(a); // undefined
a = 1;
console.log(a); // 1

코드는 이런식으로 작동한다.

그렇다고 호이스팅이 발생하지 않는 것은 아니다!

let a = 0;

{
	console.log(a); // 에러 발생!
    let a = 1;
}

원래 호이스팅이 되지 않는다면 0이 출력되어야 맞지만, 에러가 발생한다!

결국 let 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것 처럼 보이지만, 발생한다는 것!

이렇게 자바스크립트에만 있는 특별한 동작원리 호이스팅에 대해 알아보았다!

profile
점을 찍는 개발자🌱

0개의 댓글