코딩일상
호이스팅?? TDZ는 무엇일까 ? 본문
들어가기 앞서 보면 좋은 글
호이스팅이란??
Hoisting은 ”끌어올리다”라는 뜻을 가지고 있습니다.
JavaSciprt에서의 Hoisting은 선언되지 않은 함수, 변수(var로 선언된),
import구문을 상단으로 끌어올려 사용할 수 있게 하는 방식을 의미합니다.
호이스팅
스코프 내부 어디서든 변수선언은 최상위에 선언된것처럼 행동
호이스팅 예시
1) 변수
console.log(name) // ReferenceError: variable is not defined
name이라는 변수를 선언해주지 않았기 때문에 위의 코드는 당연히 참조에러를 발생시킵니다.
위의 코드는 undefined가 출력됩니다. 자바스크립트 엔진은 내부적으로 위의 코드를 다음과 같이 해석합니다.
해석과정에서 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 주로 사용
레퍼런스
'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 |