JS 중급 | 변수, 호이스팅, TDZ

uoah·2023년 1월 10일
1

자바스크립트

목록 보기
16/33
post-thumbnail

🚀 오늘의 학습 목표

  • 변수
  • 호이스팅
  • TDZ (Temporal Dead Zone)
  • var / let / const 차이점 알기

1. 변수(variable)

변수는 let, const (ES6 에 도입), var 가 있다.

1-1. var / let 의 차이점

var는 한 번 선언된 변수를 다시 선언할 수 있다.

var name = 'mike';
console.log(name); // "mike"

var name = 'jane';
console.log(name);	// "jane"

let 은 한 번 선언된 변수를 다시 선언할 수 없다.

let name = 'mike';
console.log(name); // "mike"

let name = 'jane';
console.log(name); // error!
//Uncaught SyntaxError: Identifier 'name' has already been declared 

1-2. var 는 선언하기 전에 사용할 수 있다.

var 가 에러를 일으키지 않은 이유는?

console.log(name); // undefined

var name = 'mike';

var 는 아래와 같이 동작하기 때문이다.

var name ;

console.log(name); // undefined

name = 'mike';

var 로 선언한 모든 변수는 코드가 실제로 이동하지 않지만 최상위로 끌어 올려진 것처럼 동작한다. 이를 호이스팅(hoisting) 이라고 한다.

console.log 값이 undefined 가 출력되는 이유는 선언은 호이스팅 되지만 할당은 호이스팅이 되지 않기 때문이다. 할당은 세번째 줄(위의 예제에서 name = 'mike';) 에서 처리된다.

같은 상황에서 let 은 에러가 난다.

let 이 에러가 나는 이유는?

console.log(name);

let name = 'mike';
// Uncaught ReferenceError: Cannot access 'name' before initialization 

letconst호이스팅*이 된다.

호이스팅*
스코프 내부 어디에서든 변수 선언은 최상위에 선언된 것 처럼 행동하는 것을 말한다.

그런데 왜 에러가 날까.
TDZ(Temporal Dead Zone) 때문이다.

console.log(name); 		// Temporal Dead Zone 

let name = 'mike';		// 함수 선언 및 할당
console.log(name);		// 사용 가능

TDZ 영역에 있는 변수들은 사용을 할 수 없다.
letconstTDZ 에 영향을 받는다.
할당을 하기 전에는 사용할 수 없다.
이는 코드를 예측 가능하게 하고 잠재적인 버그를 줄일 수 있다.


다른 예제를 살펴 보자.

  • 아래 예제는 에러가 발생하지 않는다.
let age = 30;
function showAge() {
  console.log(age); // 30
  
}
showAge ();
  • 아래 예제는 에러가 발생한다.

호이스팅은 스코프* 단위로 일어난다. 여기에서 스코프*함수의 내부 를 말한다.
let 으로 선언한 두 번째 age 가 호이스팅이 되면서 에러를 발생한다.
만약, 호이스팅이 발생하지 않았다면 함수 바깥에서 선언한 age 30 이 정상적으로 출력되었을 것이다.

let age = 30;
function showAge() {
  console.log(age); 
  //Uncaught ReferenceError: Cannot access 'age' before initialization 
  
  let age = 20;
}
showAge ();

1-3. 변수의 생성 관계

  1. 선언 단계
  2. 초기화 단계
  3. 할당 단계

1-3-1. var

  1. 선언 및 초기화 단계
    선언과 초기화가 동시에 이뤄진다.
    그래서 할당 전에 호출하면 에러를 내지 않고 Undefined 가 나온다.
  2. 할당 단계

초기화 : undefined 를 할당 해 주는 단계

1-3-2. let

  1. 선언 단계
  2. 초기화 단계
    선언과 초기화가 단계가 분리되어 있다.
  3. 할당 단계

호이스팅 되면서 선언 단계가 이루어지지만 초기화 단계는 실졔 코드에 도달했을 때 이루어지기 때문에 ReferenceError가 발생한다.

1-3-3. const

  1. 선언 + 초기화 + 할당
    선언과 동시에 할당이 되어야 한다.

letvar는 나중에 값을 바꿀 수 있기 때문에 선언만 해 두고 나중에 할당하는 것을 허용하지만 const 는 불가하다.

아래의 예제에서는 letvar 는 에러가 발생하지 않지만, const gender 는 선언과 동시에 할당을 하지 않아 에러가 발생한다.

let name;
name = 'mike';

console.log(name); // "mike"

var age;
age = 30;

console.log(age); // 30

const gender;
gender = 'male';

console.log(gender);
// Uncaught SyntaxError: Missing initializer in const declaration 

1-4. 스코프

함수 스코프(function-scoped)블록 스코프(block-scoped)
varlet, const
  • 함수 스코프(function-scoped)
    함수 내에서만 선언된 변수만 그 지역 변수가 된다.

  • 블록 스코프(block-scoped)
    모든 코드블록에서 선언된 변수는 코드블록 내에서만 유효하며 외부에서는 접근할 수 없다.
    코드 블록 내에서 선언된 변수지역 변수이다.
    여기에서 말하는 코드 블록은 함수, if문, for문, while문, try/catch문 등을 의미한다.

0개의 댓글

관련 채용 정보