본문 바로가기

공부/javascript

javascript 심화 2 (호이스팅, var let const 차이점, TDZ)

반응형

호이스팅 📖

 

호이스팅

 

호이스팅이란? 사전에 검색해 보면 `끌어올리기`, `들어 올려 나르기`라고 나옵니다!

단어 뜻처럼 스크립트 내에 변수나 함수의 선언이 스코프 최상단으로 끌어올려지는 현상을 말합니다.

 

❗여기서 포인트는 물리적으로 끌어 올려지는 것이 아니라 코드 전체를 스캔하고 실행 컨텍스트에 미리 기록하기 때문에 이런 현상이 발생합니다!

 

실행 컨텍스트가 궁금하시면

 

javascript 심화 1 (실행 컨텍스트)

실행 컨텍스트 📖실행할 코드에 대한 `환경 정보`들을 모아놓은 `객체`입니다. 이렇게만 말하면 이해가 잘 안 될 것 같으니 더 자세하게 설명해 드리겠습니다. 우선 실행 컨텍스트를 이해하기

mingos-habitat.tistory.com

 

예시코드 (매개변수, 변수)✅

매개변수 및 변수는 선언부를 호이스팅 합니다.

function a () {
	var x = 1;
	console.log(x);
	var x;
	console.log(x);
	var x = 2;
	console.log(x);
}
a(1);

 

위 예시 코드의 실행 결과를 한 번 예상해 보세요~!

 

 


 

 

 

 

아마도 `1 -> undefined -> 2` 순으로 출력이 될 거라고 많이 예상들 하셨겠지만 ❌

 

예시코드(호이스팅 적용) ✅

function a () {
	var x;
	var x;
	var x;

	x = 1;
	console.log(x);
	console.log(x);
	x = 2;
	console.log(x);
}
a(1);

 

실제론 `1 -> 1 -> 2`가 출력이 됩니다.🧐

 

예시코드 (함수)✅

함수 선언은 전체를 호이스팅 합니다.*함수라고 해서 무조건 다 호이스팅 되는 건 아닙니다! 아래에서 설명해 드릴게요~

//action point 1 : 결과 값 예상해보기
//action point 2 : hoisting 적용해본 후 결과를 다시 예상해보기

function a () {
	console.log(b);
	var b = 'bbb';
	console.log(b);
	function b() { }
	console.log(b);
}
a();

 

위 예시 코드의 실행 결과를 한 번 예상해 보세요~!

 

 


 

 

 

`오류 -> bbb -> function` 순으로 출력될 것이라 예상하시겠지만 ❌

 

예시코드(호이스팅 적용) ✅

function a () {
	var b; // 변수 선언부 호이스팅
	function b() { } // 함수 선언은 전체를 호이스팅

	console.log(b);
	b = 'bbb'; // 변수의 할당부는 원래 자리에

	console.log(b);
	console.log(b);
}
a();

 

실제론 `function -> bbb -> bbb`가 출력이 됩니다.🧐

호이스팅을 예상하기 전이랑 결과가 다르게 나옵니다. 이처럼 호이스팅을 고려하지 않고 결과를 예측하기 매우 어렵다는 것입니다.

 

 

함수의 호이스팅 📖

예시코드 ✅

`함수 선언문` : 함수 정의부만 존재하고 할당 명령이 없는 경우

`함수 표현식` : 함수를 별도 변수에 할당하는 경우

console.log(sum(1, 2));
console.log(multiply(3, 4));

function sum (a, b) { // 함수 선언문 sum
	return a + b;
}

var multiply = function (a, b) { // 함수 표현식 multiply
	return a + b;
}

 

 

`함수 선언문` 같은 경우에는 전체가 위로 쭉 끌어올려지지만 `함수 표현식` 같은 경우에는 변수에 할당하기 때문에 선언부만 호이스팅 되는 걸 볼 수 있습니다.

// 함수 선언문은 전체를 hoisting
function sum (a, b) { // 함수 선언문 sum
	return a + b;
}

// 변수는 선언부만 hoisting

var multiply; 

console.log(sum(1, 2));
console.log(multiply(3, 4));

multiply = function (a, b) { // 변수의 할당부는 원래 자리
	return a + b;
};

 

협업을 많이 하고, 복잡한 코드일수록 `함수 표현식`을 활용하는 습관을 가지는 게 좋습니다!

 

 

var, let, const 차이점 📖

var, let, const

`var` 키워드는 재선언, 재할당이 가능합니다.

var greeter = "hey hi";
var greeter = "say Hello instead";

var greeter = "hey hi";
greeter = "say Hello instead";

 

`let` 키워드는 재선언은 불가능하지만 재할당은 가능합니다.

let greeting = "say Hi";
let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared

let greeting = "say Hi";
greeting = "say Hello instead";

 

`const` 키워드는 재선언, 재할당 모두 불가능합니다.

const greeting = "say Hi";
greeting = "say Hello instead";// error: Assignment to constant variable.

const greeting = "say Hi";
const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared

 

변수 호이스팅 방식

변수는 `선언` -> `초기화` -> `할당`에 걸쳐 생성되는데

 

`var` 키워드로 선언한 변수는 `선언`, `초기화`가 동시에 이뤄집니다.

console.log(name); // undefined
var name = "Anna";
console.log(name); //Anna

 

하지만 할당은 되지 않았기 때문에 첫 번째 줄에 console.log(name)은 `선언`과`초기화`가 된  var name;을 출력하기 때문에`undefined`를 출력하게 됩니다.

 

 

`let` `const`키워드로 선언한 변수는 `선언`과`초기화`가 분리되어 진행됩니다.

코드 실행 전에는 변수 선언만 해두며 초기화는 변수 선언문을 만났을 때 수행합니다.

console.log(a);  // ReferenceError :: 변수 선언 이전에 변수 참조 불가능

let a  // 초기화

console.log(a);  // undefined

a = 10  // 할당

consloe.log(a);  // 10

 

그리고 `var` 키워드와는 다르게 선언된 변수를 앞에서 참조하려고 할 때 `ReferenceError`가 발생합니다.

하지만 오류가 발생해서 호이스팅이 발생하지 않는 것처럼 보이지만 접근만 하지 못하게 된 것입니다. 여기서 `TDZ(Temporal Dead Zone)`에 대한 개념이 나옵니다.

 

TDZ(Temporal Dead Zone)

`TDZ`를 한글로 하면 일시적인 사각지대란 뜻입니다.

let과 const을 사용할 때 변수 선언 및 초기화하기 전 값에 접근하게 되면 되면 ReferenceError가 발생하게 됩니다.  

 

반응형