변수 선언과 스코프와 호이스팅

ssummer·2023년 9월 10일
post-thumbnail

지역 변수가 선언될 땐 스코프의 범위가 함수레벨과 블록레벨로 나뉘어진다.

var

함수레벨의 예시문은

const myFunction = function() {
	var x = 0;
}

블록레벨의 예시문은

if() {
	var y = 0;
}

함수레벨에서는 함수의 중괄호를 벗어날 수 없어서 함수 중괄호 다음에 console로 변수 x를 찍어보면 undefined가 출력되고 블록레벨에서는 중괄호를 벗어날 수 있으므로 변수 y값이 출력된다.

전역변수로 var i = 100;을 선언했다고 하자.

for(var i = 0; i < 10; i = i + 1) {
	console.log(i);
}
console.log(i);

위 코드를 실행시켜보면 100이 아닌 10이 출력된다. 블록레벨 스코프를 탈출한 것이다.
이렇게 var 키워드로 변수를 선언하면 블록레벨 스코프를 탈출한다는 문제점이 있다.


let

let 키워드는 블록레벨 스코프도 따른다.

if() {
	let y = 0;
}
console.log(y);

위 코드를 실행하면 undefined가 출력된다. 같은 문을 var 키워드로 선언했을 때와는 다른 출력값이다. 이렇게 let 키워드를 사용하면 의도치않은 변수 재할당을 피할 수 있다.


글로벌 스코프는 스크립트 스코프(스크립트가 실행되는 범위)보다 상위 스코프이다. 브라우저에서 사용되는 객체들이 존재한다.(ex - cookie, fetch, document 등)
var 키워드로 변수를 선언하게 되면 스크립트 스코프를 벗어나기 때문에 옳지 않다.

var document = 1;

위의 코드를 실행하면 기존의 document 객체가 할당된 변수가 재할당되는 위험한 일이 생긴다.

스코프체이닝
디버깅을 하면서 해당 변수가 어떤 스코프에 존재하는지 하위에서 상위로 타고 올라가며 탐색하는 것


호이스팅

var 키워드로 변수를 선언하면 변수 호이스팅이 일어나 undefined가 출력되고
let 키워드로 변수를 선언하면 변수 호이스팅이 일어나지 않고 런타임에 같이 읽히기 때문에 참조 오류가 일어난다.
var 키워드로는 오류를 미연에 방지할 수 없다.

변수 선언문이 실행될 땐 선언단계 - 초기화단계 - 할당단계를 거친다.
선언단계와 초기화단계 사이에 TDZ(Temporal Dead Zone)가 존재한다.

var

var 키워드는 선언과 초기화가 묶여서 실행된다.

let, const

let 키워드와 const 키워드로 선언된 변수도 변수 호이스팅이 일어난다. 하지만 TDZ에 머물러 초기화가 되지 않아 참조 오류가 일어나는 것이다. 이때문에 호이스팅이 일어나지만 일어나지 않는 것처럼 보인다.

함수 선언식은 TDZ의 영향을 받지 않는다.

function fn() {
	console.log("TDZ의 영향을 받지 않았어요."):
}

반면에 함수 표현식은 TDZ의 영향을 받는다.

const fn = function() {
	console.log("TDZ의 영향을 받았어요.");
}

소스코드의 위쪽에서 참조오류가 발생하면 해당 함수 표현식을 코드의 아래쪽으로 옯겨 해결한다.

0개의 댓글