Javascript : 스코프, 호이스팅, TDZ

HaByungNo·2022년 7월 21일
0
post-thumbnail

이미지 출처 링크

스코프(scope)

스코프(scope)는 현제 실행되는 컨텍스트(context)를 말한다. 여기서 컨텍스트는 값과 표현식이 "표현"되거나 참조 될 수 있음을 의미한다. 만약 변수 또는 다른 표현식이 "해당 스코프"내에 있지 않다면 사용할 수 없다. 스코프는 또한 계층적인 구조를 가지기 때문에 하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가하다.

  • context 의 사전적 의미
    (명사)
    1. (어떤 일의) 맥락, 전후 사정
    2. (글의) 맥락, 문맥

함수는 자바스크립트에서 클로저 역할을 하기 때문에 스코프를 생성하므로 함수 내에 정의된 변수는 외부 함수나 다른 함수 내에서는 접근 할 수 없다. 예를 들어 다음과 같은 상황은 유효하지 않다.

실습 예제 (스코프)

let b = 1;     

function hi() {
    const a = 1;
    let b = 100;
    b++;
    console.log(a, b); 
}

// console.log(a);
console.log(b); 
hi();
console.log(b);  

이 상태에서 실행시키면 콘솔에는 다음과 같이 찍힐 것이다.

1 			
1, 101  
1      

1번째 줄의 1 은 예제 코드의 1행에서 선언된 b의 값이 찍힌것이고
2번째 줄의 1, 101 은 예제 코드의 4행에서 선언된 a 와 5행에서 선언된 b 에서 b++ 된 값이 찍힌것이며
마지막 3번째 줄 1 은 다시 예제코드 1행의 b값이 찍힌것디다.


만약 예제코드 10행 부분의 주석을 푼다면

console.log(a); //ReferenceError

ahi() 함수 안에서 선언된 지역변수 이므로 전역변수처럼 호출하면 ReferenceError 가 나게된다.

a 변수를 찍어보고 싶다면
console.log(a)hi() 함수 블럭 안으로 옮기거나, 10번째 줄 이전에 a 전역 변수 선언을 해주어야 한다.


호이스팅(hoisting)

JavaScript에서 호이스팅(hoisting) 이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다. var로 선언한 변수의 경우 호이스팅 시 undefined 로 변수를 초기화한다. 반면 letconst 로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않는다.

실습 예제 (호이스팅)

JavaScript는 함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당한다. 덕분에 함수를 호출하는 코드를 함수 선언보다 앞서 배치할 수 있다. 예를 들어,

function catName(name) {
  console.log("제 고양이의 이름은 " + name + "입니다");
}

catName("호랑이");

/*
결과: "제 고양이의 이름은 호랑이입니다"
*/

위의 코드 조각이 일반적으로 코드를 작성하는 순서라면,
함수를 선언하기 전에 먼저 호출했을 때의 예제도 보자.

catName("클로이");

function catName(name) {
  console.log("제 고양이의 이름은 " + name + "입니다");
}

/*
결과: "제 고양이의 이름은 클로이입니다"
*/

함수 호출이 함수 자체보다 앞서 존재하지만, 이 코드는 동작한다. 이것이 JavaScript에서 실행 맥락이 동작하는 방식이다.

호이스팅은 다른 자료형과 변수에도 잘 작동한다. 변수를 선언하기 전에 먼저 초기화하고 사용할 수 있는 것.

선언만 호이스팅 대상

JavaScript는 초기화를 제외한 선언만 호이스팅한다. 변수를 먼저 사용하고 그 후에 선언 및 초기화가 나타나면, 사용하는 시점의 변수는 기본 초기화 상태(var 선언 시 undefined, 그 외에는 초기화하지 않음)다. 예를 들어,

console.log(num); // 호이스팅한 var 선언으로 인해 undefined 출력
var num; // 선언
num = 6; // 초기화

반면, 다음 예제는 선언 없이 초기화만 존재한다. 따라서 호이스팅도 없고, 변수를 읽으려는 시도에서는 ReferenceError 예외가 발생합니다.

console.log(num); // ReferenceError
num = 6; // 초기화

let 과 const

let과 const로 선언한 변수도 호이스팅 대상이지만, var와 달리 호이스팅 시 undefined로 변수를 초기화하지는 않는다. 따라서 변수의 초기화를 수행하기 전에 읽는 코드가 먼저 나타나면 예외가 발생한다.

letconst 더 알아보기



TDZ (temporal dead zone)

1. const

const num = 1

num; // 1

위 코드는 정상적으로 동작한다

num; // throws `ReferenceError`
const num = 1

num; // 1

const num = 1 구문 위의 num 은 TDZ에 있다.
ReferenceError: Cannot access 'white' before initialization
자바스크립트 에러가 발생한다.

그림 출처: https://dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/

2. let

let 도 const와 같이 선언 줄 까지 TDZ의 영향을 받는다.

// Does not work!
count; // throws `ReferenceError`
let count;

count = 10;

따라서 let 변수도 선언 이후에 사용해야 한다.

3. class 구문

4. constructor() 내부의 super()

5. 기본 함수 매개변수(Default Function Parameter)


레퍼런스:

https://developer.mozilla.org/ko/docs/Glossary/Scope
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
https://ui.toast.com/weekly-pick/ko_20191014?fbclid=IwAR3fiR4wiv8kszL6Fz2KqwHpv-bTL8tNHElRN0q0ky5kpOP5BMqMS0wc-9k

profile
프라고

0개의 댓글