프론트엔드 개발/JavaScript

자바스크립트) 변수, TDZ

Ella Seon 2023. 8. 3. 18:40

 

0. 변수

- 변수(Variable)는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이다.
- 변수는 프로그래밍 언어에서 값을 저장하고 참조하는 메커니즘으로, 값의 위치를 가리키는 상징적인 이름이다.
- 프로그래밍 언어의 컴파일러 또는 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행된다. 따라서 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조할 필요가 없고 변수를 통해 안전하게 값에 접근할 수 있다. 

- 식별자(변수명) : 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름

- 변수 값 : 변수에 저장된 값

- 할당 : 변수에 값을 저장

- 참조 : 변수에 저장된 값을 읽어들이는 것

 

1. 변수 선언 (변수를 생성하는 것)

- 1) 값을 저장하기위해 메모리 공간을 확보하고 

- 2) 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비하는 것

 

변수 선언에 의해 확보된 메모리 공간은 확보가 해체(release)되기 전까지는 누구도 확보된 메모리 공간을 사용할 수 없도록 보호되므로 안전하게 사용할 수 있다.

변수를 사용하려면 반드시 선언이 필요하다. 변수를 선언할 때는 var, let, const 키워드를 사용한다.

 

🔸변수 생성 단계

1) 변수 선언 

변수를 실행컨텍스트 변수 객체에 등록하는 단계
이 변수객체는 스코프가 참조하는 대상이 된다. 

let age ;  // 선언
2) 변수 초기화 :

메모리에 변수 저장을 위해 공간을 확보하는 단계, 기본값으로 undefined가 할당된다.
일반적으로 초기화란 변수가 선언된 이후 최초로 값을 할당하는 것을 말한다.



let age; // 선언 -> 초기화
console.log(age); // undefined
3) 값 할당

할당 연산자(=)를 사용해 값을 할당한다.
undefined로 초기화된 변수에 실제 값을 할당해주는 단계
모든 선언 키워드의 할당은 런타임 과정에서 이루어짐

let age; // 선언 -> 초기화
console.log(age); // undefined

age = 20; // 값 할당
console.log(age); // 20

 

2. 변수 선언 키워드 (var, let, const)

변수 선언은 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이전 단계에서 먼저 실행된다.

const 는 값을 재할당 하지 못하므로 선언만 단독으로 불가함. const 변수는 상수이기 때문에 단 한번만 값을 할당할 수 있다. 

 

 

- var 키워드를 사용한 변수는 선언 단계와 초기화 단계가 동시에 진행된다.
- var score; 는 선언 단계를 통해 변수 이름 score를 등록하고, 초기화 단계를 통해 score 변수에 암묵적으로 undefined를 할당해 초기화 한다.




변수에 값을 할당할 때는 이전 값 undefined가 저장되어있던 메모리 공간을 지우고 그 메모리 공간에 80을 할당하는 것이 아닌 새로운 메모리 공간을 확보하고 그 곳에 값 80을 저장한다는 점을 주의하자
var는 선언과 초기화가 동시에 이루어지기 때문에, 호이스팅 시 초기화도 이루어져 undefined라는 값이 할당된다. 따라서, 변수 선언 전에 참조할 수 있으며, 이 때 undefined를 반환한다.
let 으로 선언한 변수는 선언단계와 초기화 단계가 분리되어 실행된다. 즉,호이스팅으로 선언단계가 먼저 이루어지지만, 초기화 단계는 변수 선언문에 도달했을 때 이루어진다. 초기화 이전에 변수에 접근하려고 하면 참조에러(ReferenceError)가 발생한다. 이는 변수가 아직 초기화 되지 않았기 때문이다. 다시 말하면 변수를 위한 메모리 공간이 아직 확보되지 않았기 때문이다. 

즉, TDZ(일시적 사각지대) 로 인해 에러가 난다.
const로 선언한 변수는 선언, 초기화, 할당 단계가 동시에 이루어진다.
const 는 변수를 선언할 때 반드시 값을 할당해야함
그렇지 않으면 문법 오류가 발생한다.

일시적 사각지대 때문에 referenceError가 난다.

 

🔸일시적 사각지대

변수가 선언되었지만, 초기화(메모리 할당) 되기 전까지의 구간으로 변수를 참조할 수 없는 구간

tdz에서는 선언 되기 전이나 초기화 되기 전인 상태의 변수를 사용하는 것을 허용하지 않는다. 

let,const 는 TDZ에 영향을 받는다. let,const가 호이스팅 되어서 최상위에 선언된 것처럼 되었다고 해도, 변수에 값이 할당이 되기 전까지는 사용할 수 없도록 만들어 놓은 것이 TDZ

let과 const는 var 과 다르게 선언 단계와 초기화 단계가 따로 분리되어 실행된다. 그래서 선언 단계와 초기화 단계 사이에서는 변수를 등록했지만 메모리가 할당되지 않은 상태라 “ReferenceError”가 나오게 된다. 이런 사각지대를 TDZ라고 한다.

 

4. var 키워드의 문제점

1. 변수의 중복 선언 허용
2. 함수 레벨 스코프이기 때문에 함수가 아닌 다른 블록 스코프에서 선언된 변수는 모두 전역변수로 취급되어 예기치 못한 할당
3. 변수 호이스팅으로 인해 선언 전에 변수를 참조하면 undefined가 될 수 있다. 

1. 변수의 중복 선언 허용

var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언이 허용되는데, 이는 의도치 않게 변수값이 재할당되어 변경되는 부작용을 발생시킨다.

2. 함수레벨 스코프

대부분의 프로그래밍 언어는 함수 몸체만이 아니라 모든 코드 블록(if, for, while, try/catch 등)이 지역 스코프를 만든다. 이러한 특성을 블록 레벨 스코프라 한다. 하지만 var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정한다. 이러한 특성을 함수 레벨 스코프라 한다.

function func() {
  const x = 10;
}
if (true) {
  var y = 20;
}
console.log(x); // Uncaught ReferenceError: x is not defined
console.log(y); //20  함수레벨 스코프이기 때문에 블록 안에 선언된것도 전역변수처럼 취급될 수 있다.

3. 호이스팅으로 선언 전에 변수를 참조하면 undefined가 될 수 있음

var 키워드로 선언된 변수는 선언과 동시에 undefined로 초기화되며, 런타임 즉 소스코드 평가 단계에서 스코프에 등록되기 때문에 실행 단계에서 실제 값이 할당되지 않더라도 undefined를 가지고있다. 이를 변수 호이스팅이라 한다.

 


참고자료

https://curryyou.tistory.com/277

 

[자바스크립트] 코드 실행 2단계와 변수/함수 생성 과정

자바스크립트는 소스 코드를 2단계로 실행합니다. 1 단계: 실행 컨텍스트 생성하고, 변수 등을 등록하는 단계 2 단계: 소스 코드를 한 줄씩 실행하는 단계 이 글은 각각의 과정을 최대한 단순화하

curryyou.tistory.com