2022. 11. 18. 16:13ㆍ웹 개발/javascript
이번 포스팅에서는 호이스팅과 TDZ에 관한 글을 작성하려고 한다.
스코프 : 변수, 함수, 클래스가 접근할 수 있는 유효 범위
호이스팅 : 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미
TDZ(Temporal Dead Zone) : 참조 오류가 나는 구간인 스코프 시작지점부터 초기화 지점까지의 구간
1. 스코프
자바스크립트의 스코프는 함수 레벨 스코프를 따른다.
같은 함수 레벨에 존재하면 값을 참조할 수 있다는 것인데, ES6에서 let 키워드가 도입되면서 블록 레벨 스코프를 사용할 수 있게 되었다.
전역 스코프
- 어디서든 참조 가능
전역 변수
- 전역 스코프를 갖는 전역 변수
- 어디서든 참조 가능
지역 스코프
- 함수 자신과 하위 함수에서만 참조 가능
지역 변수
- 지역 스코프를 갖는 지역 변수
- 함수 내에서 선언된 변수로 해당 함수와 해당 함수의 하위 함수에서 참조 가능
암묵적 전역 변수
- 선언하지 않은 변수에 값을 할당하면 전역 객체의 프로퍼티가 되어 전역 변수처럼 동작한다.
하지만 변수 선언이 없었기 때문에 호이스팅은 발생하지 않는다.
2. 호이스팅(hoisting)
인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다.
var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화 한다.
let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화 하지 않는다.
호이스팅 대상
- var와 함수 선언문이 호이스팅 대상이다.
- let 또는 const, 함수 표현식은 해당되지 않는다.
호이스팅 규칙
- 변수 선언 > 함수 선언
- 할당되어 있는 변수 > 할당되지 않은 변수
아직 잘 이해가 되지 않는다. 좀 더 문서를 살펴보자
변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는 것
변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있다고 한다. 그러나 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하라

원래 코드를 작성할 때 catName과 같이 먼저 함수를 작성하고 나중에 call 하는 방식으로 했는데
먼저 함수를 호출하고 선언해도 제대로 작동 된다는 것을 알 수 있다.
함수만 해당되는 것이 아니라, 호이스팅은 다른 자료형과 변수에도 잘 작동한다.
변수 선언 형식에 따른 초기화
var : 호이스팅 시 undefined로 변수를 초기화
function : 선언된 위치와 상관없이 동일하게 호출
let, const : 호이스팅 시 변수를 초기화하지 않음. ( 호이스팅 대상은 맞음 )
+ 함수 선언식과 함수 표현식에서 호이스팅 방식의 차이
1. 함수 선언식에서의 호이스팅 방식
위의 function catName()과 dogName()함수는 함수 선언식에서의 호이스팅 방식을 보여준다.
즉, 어떻게 써도 둘 다 정상 작동한다는 뜻이다.
2. 함수 표현식에서의 호이스팅 방식
다음의 세 가지 예제가 있다.

다음은 count() 호출 후, var count를 선언하며 함수를 담았다.
var는 호이스팅의 영향을 받으므로 가장 위로 끌어올려진다.
var count;가 가장 먼서 실행되고 변수에 아무 값도 담지 않았으므로 undefined 상태이다.
그 후 count()가 호출되면 위에 선언한 count가 호출되므로 변수를 호출하는 것이된다
따라서 not function 이라는 에러 메세지가 나오게 된다.

두번째는

위는 정상적으로 작동한다.
var count가 호이스팅으로 인해 위로 끌어올려지지만, count(); 호출 전에 count에 함수를 선언하였으므로 count() 호출 시에 정상 작동한다.
세번째는

첫 번째와는 다른 ReferenceError 에러가 발생한다.
let은 호이스팅의 영향을 받지 않기 때문에, 예시 작성한 코드 순서대로 실행된다.
count()라는 함수가 정의되지 않았는데 호출했기 때문에 에러가 발생한다.
3. TDZ(Temporal Dead Zone, 일시적 사각지대)

(출처 : https://dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/ )
TDZ 시맨틱은 선언 전에 변수에 접근하는 것을 금지한다. 변수 선언 전에 어떤 것도 사용하지 않는다.
- const, let 변수와 class 구문은 선언 이후에 사용해야 한다.
- 기본 함수 매개변수에서 기본 매개번수는 글로벌과 함수 스코프 사이의 중간 스코프에 위치한다. 기본 매개변수 또한 TDZ 제한이 있다.
- var, function 선언은 TDZ에 영향을 받지 않고, import 모듈 역시 호이스팅이 된다.
- var의 사용은 의도치 않은 중복 선언과 재할당으로 문제가 생길 수 있기 때문에 사용하지 않는 편이 좋다.
== Reference ==
https://bbangaro.tistory.com/62
[JavaScript] 스코프와 호이스팅 그리고 TDZ (Scope, Hoisting, Temporal Dead Zone)
스코프랑 호이스팅은 대략적으로 알고 있다고 생각했는데 1년 전에 잠시 스쳐 지나갔던 TDZ는 오랜만에 보니 또 새롭다. 스코프 자바스크립트의 스코프는 함수 레벨 스코프를 따른다. 같은 함수
bbangaro.tistory.com
호이스팅
함수선언문, 함수표현식과 호이스팅
javascript 코드를 보면 다음과 같은 경우를 보았을 것이다. javascript 에서 함수를 변수에 담을 수 있다.이렇게 사용하는 것을 함수 표현식 이라고 한다.그리고 function getName() 과 같이 함수를 선언하
velog.io
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
호이스팅 - 용어 사전 | MDN
JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다
developer.mozilla.org
그래서 호이스팅의 장점이 뭔데
제가 코어자바스크립트의 2장 실행컨텍스트를 읽고 한 생각입니다. 애초에 질문 부터가 틀렸다. 호이스팅은 JS 동작 그 자체이다. 위의 질문보다는 호이스팅때문에 발생하는 에러를 피하기 위해
velog.io
TDZ
https://ui.toast.com/weekly-pick/ko_20191014
TDZ을 모른 채 자바스크립트 변수를 사용하지 말라
간단한 질문을 하나 하겠다. 아래 코드 스니펫에서 에러가 발생할까? 첫 번째 코드는 인스턴스를 생성한 다음 클래스를 선언한다.
ui.toast.com
'웹 개발 > javascript' 카테고리의 다른 글
| 실습 예제 (0) | 2022.11.19 |
|---|---|
| 실행 컨텍스트와 콜 스택, 스코프 체인, 변수 은닉화 (0) | 2022.11.18 |
| JavaScript 객체와 불변성 (0) | 2022.11.18 |
| JavaScript의 자료형과 JavaScript만의 특성 (0) | 2022.11.18 |
| 05-2 함수 (0) | 2022.11.11 |