코딩일상
호이스팅?? TDZ는 무엇일까 ? 본문
들어가기 앞서 보면 좋은 글
호이스팅이란??
Hoisting은 ”끌어올리다”라는 뜻을 가지고 있습니다.
JavaSciprt에서의 Hoisting은 선언되지 않은 함수, 변수(var로 선언된),
import구문을 상단으로 끌어올려 사용할 수 있게 하는 방식을 의미합니다.
호이스팅
스코프 내부 어디서든 변수선언은 최상위에 선언된것처럼 행동
호이스팅 예시
1) 변수
console.log(name) // ReferenceError: variable is not defined
name이라는 변수를 선언해주지 않았기 때문에 위의 코드는 당연히 참조에러를 발생시킵니다.
위의 코드는 undefined가 출력됩니다. 자바스크립트 엔진은 내부적으로 위의 코드를 다음과 같이 해석합니다.
![](https://blog.kakaocdn.net/dn/d7IkEL/btrHQoRDhsX/ADueuJkxbepVnIguWB3Zyk/img.png)
해석과정에서 name에 대한 선언은 이루어져있는데,
값에 대한 정의가 이루어져있지 않아 undefined가 됩니다.
이처럼 자바스크립트는 해석과정에서 변수(var로 선언된), 함수, import구문을
실행 context의 최상단으로 끌어올려(호이스팅) undefined를 할당합니다.
2) 함수
sayHi('noah')
function sayHi(name) {
console.log(`${name} Says hi~`)//noah Says hi~
위의 코드도 자바스크립트 엔진이 다음과 같이 hoisting하여 해석합니다.
function sayHi(name) {
console.log(`${name} Says hi~`) //noah Says hi~
}
sayHi('noah')
hoisting은 되지만 TDZ가 생성되어 접근할 수 없어 Reference Error(참조에러)를 던지는 친구들이 있습니다.
Temporal Dead Zone(TDZ)에 들어가기 앞서
간단한 질문을 하나 하겠다. 아래 코드 스니펫에서 에러가 발생할까?
첫 번째 코드는 인스턴스를 생성한 다음 클래스를 선언한다.
new Car('red'); // Does it work?
class Car {
constructor(color) {
this.color = color;
}
}
두 번째 코드는 함수를 실행한 다음 함수를 선언한다.
greet('World'); // Does it work?
function greet(who) {
return `Hello, ${who}!`;
}
정답은 다음과 같다. 첫 번째 코드에서는 ReferenceError 에러가 발생하고, 두 번째 코드는 잘 동작한다.
만약 예상한 답과 다르거나 어떤 일이 일어나는지 잘 모르고 추측만 했다면, 당신은 Temporal Dead Zone(TDZ)을 알 필요가 있다.
TDZ은 let, const, class 구문의 유효성을 관리한다. 자바스크립트에서 변수가 동작하는 방식은 중요하다.
TDZ로 인해 생기는 오류
const white = '#FFFFFF';
white; // => '#FFFFFF'
이번에는 선언 전에 white 변수에 접근해보도록 하겠다.
white; // throws `ReferenceError`
const white = '#FFFFFF';
white
const white = '#FFFFFF' 구문 전 줄까지, white 변수는 TDZ에 있다.
TDZ에 있는 white 변수에 접근하게 되면 ,
ReferenceError: Cannot access 'white' before initialization 자바스크립트 에러가 발생한다.
그러면 왜 순서를 바꾸고 나서 오류가 발생했을까요??
이를 알기 위해서 는 우선 변수의 생성과정을 알아야 합니다.
변수의 생성과정
- 선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미합니다. 이 변수 객체는 스코프가 참조하는 대상이 됩니다.
- 초기화 단계(Initialization phase) : 실행 컨텍스트에 존재 하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계 입니다. 이 단계에서 할당된 메모리에는 undefined로 초기화 됩니다.
- 할당 단계(Assignment phase) : 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계 입니다.
var,let,const의 선언과정
위 와 같이 var,let,const 변수들의 생성과정이 다른데
이 생성과정 중 변수를 선언 및 초기화 하기전에 사용하게 되면
TDZ 상태에서 사용하는 것 이기 때문에 ReferenceError 에러가 나타나게 됩니다 !!
TDZ에 영향을 받는 구문
- const 변수
- let 변수
- class 구문
- constructor() 내부의 super()
- 기본 함수 매개변수
1. const 변수
변수를 선언 및 초기화 하기 전에 사용
console.log(cat)
const cat = "야옹"
//error : ReferenceError
변수를 선언 및 초기화 후 에 사용
const cat = "야옹"
console.log(cat)
// 출력 : 야옹
TDZ관점에서 설명
const 변수는 선언 및 초기화 전 줄까지 TDZ에 있다.
// Does not work!
pi; // throws `ReferenceError`
const pi = 3.14;
const 변수는 선언한 후에 사용해야 한다.
const pi = 3.14;
// Works!
pi; // => 3.14
2. let 변수
변수를 선언 및 초기화 하기 전에 사용
count;
let count;
count = 10;
//error : ReferenceError
변수를 선언 및 초기화 후 에 사용
let count;
count; // => undefined
count = 10;
count; // => 10
TDZ관점에서 설명
let도 선언 전 줄까지 TDZ의 영향을 받는다.
// Does not work!
count; // throws `ReferenceError`
let count;
count = 10;
다시, let 변수도 선언 이후에 사용해야 한다.
let count;
// Works!
count; // => undefined
count = 10;
// Works!
count; // => 10
3. class 구문
변수를 선언 및 초기화 하기 전에 사용
const myCar = new cat('mimi')
class cat {
constructor(name) {
this.name = name;
}
}
//error : ReferenceError
변수를 선언 및 초기화 후 에 사용
class cat {
constructor(name) {
this.name = name;
}
}
const myCat = new cat('mimi')
console.log(myCat.name) // => mimi
TDZ관점에서 설명
선언 전에는 class를 사용할 수 없다.
// Does not work!
const myNissan = new Car('red'); // throws `ReferenceError`
class Car {
constructor(color) {
this.color = color;
}
}
이 예제가 동작하려면, 클래스를 선언한 후에 사용하도록 수정한다.
class Car {
constructor(color) {
this.color = color;
}
}
// Works!
const myNissan = new Car('red');
myNissan.color; // => 'red'
TDZ에 영향을 받지 않는 구문
- var,
- function
- import 구문
// Works!
value; // => undefined
var value;
// Works!
hello('Shin') // "Hello Shin :)"
function hello (name) {
return `Hello ${name} :)`
}
hello('Shin') // "Hello Shin :)"
결론
- TDZ에 영향을 미치는 const, let, class 를 사용할 때 항상 순서를 주의해서 사용해야함
- TDZ는 선언하기 전에 변수를 사용하는 것을 허용하지 않는 다
- var 변수는 선언 전에도 사용할 수 있기 때문에 오류를 일으키는 원인이 될 수 있다.
- 가급적 var 사용은 피하고 let과 const 주로 사용
레퍼런스
Temporal Dead Zone, Hoisting에 관하여
안녕하세요 :) Noah입니다. 이글은 원문을 스터디하며 내용을 덧붙여 쓴 글 입니다. 원문 : Don’t Use JavaScript Variables Without Knowing Temporal Dead Zone, TDZ을 모른 채 자바스크립트 변수를 사용하지 말라 Ho
noah0316.github.io
What is the temporal dead zone?
I've heard that accessing let and const values before they are initialized can cause a ReferenceError because of something called the temporal dead zone. What is the temporal dead zone, how does it
stackoverflow.com
TDZ을 모른 채 자바스크립트 변수를 사용하지 말라
간단한 질문을 하나 하겠다. 아래 코드 스니펫에서 에러가 발생할까? 첫 번째 코드는 인스턴스를 생성한 다음 클래스를 선언한다.
ui.toast.com
'Etc > 항해99과제' 카테고리의 다른 글
항해 99과제 주특기심화과정5주차 (7) | 2022.08.12 |
---|---|
package.json이란?? (0) | 2022.07.31 |
자바스크립트 기본형 데이터 와 참조형 데이터 (0) | 2022.07.21 |
JavaScript 객체와 불변성이란 ? (0) | 2022.07.21 |
항해99 실습과제 (0) | 2022.07.20 |