var,let,const 차이점

shw·2022년 7월 3일
0

var는 중복 선언이 가능하다.

var name = "Seol";
console.log(name); // Seol
var name = "hw";
console.log(name); // hw

이는 변수를 유연하게 사용할 수 있다는 장점이 될 수 있지만, 몇백줄 몇천줄의 코드에서 기존에 선언한 변수에 재할당하게 되는 실수가 발생할 수 있는 위험이 있고 찾기도 어렵다.

let은 중복 선언은 불가능하고 재할당은 가능하다.

let name = "Seol";
console.log(name); // Seol
let name = "hw";
console.log(name); // Uncaught SyntaxError: Identifier 'name' has already been declared 
name = "Seolhw";
console.log(name); // Seolhw

let으로 이미 선언한 변수 name에 다른 값을 넣었을 때 이미 name이라는 변수가 선언 되었다는 에러가 출력된다.
그러나 name = "Seolhw"; 처럼 값을 재할당 하는것은 가능하다.

const는 중복 선언, 재할당 모두 불가능하다.

const name = "Seol";
console.log(name); // Seol

const name = "hw";
console.log(name); // Uncaught SyntaxError: Identifier 'name' has already been declared

name = "Seolhw";
console.log(name); // Uncaught TypeError: Assignment to constant variable.

const로 선언한 변수 name에 값을 "hw"로 중복선언 했을 경우 let과 같은 에러 메시지가 출력되었다.
그리고 name에 값을 재할당 했을 때 let과 달리 에러 메시지가 출력되었다.

호이스팅

먼저 호이스팅이란 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다. 쉽게 변수와 함수의 선언을 해당 스코프의 최상단으로 끌어올려서 선언하는 것이다.
실제로 코드가 바뀌는 것은 아니며, 자바스크립트의 파서(Parser)가 함수 실행 전에 내부적으로 선언문을 끌어올려서 처리한다.
호이스팅은 모든 변수와 함수선언식에 영향을 미친다. 그러나 var와 달리 let과 const는 일시적 사각지대(TDZ : Temporal Dead Zone)에 의해 호이스팅 되지 않은것처럼 보인다.

TDZ란?

TDZ란 변수가 선언되고 초기화되기의 범위를 TDZ(Temporal Dead Zone)에 있다고 한다.

1) var

console.log(myName); // undefined

var myName = "taenami";

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

위와 같이 선언한 myName이라는 변수는 error가 발생하는 대신, undefined가 나오는데, var로 선언된 변수는 *호이스팅 되기 때문이다.

2) let, const

console.log(myName); // ReferenceError

let myName = "taenami";
console.log(myName); // ReferenceError

const myName = "taenami";

let과 const로 선언된 변수은 선언하기 전에 사용할 수 없다.
위와 같은 에러가 발생한다고 해서, 호이스팅 되지 않는 것이 아니다.

let과 const로 선언된 변수는 TDZ (Temporal Dead Zone)에 영향을 받기 때문인데, TDZ에 있는 변수들은 사용할 수 없습니다. TDZ에 대해서 알아보기 위해 다음으로 변수의 생성과정을 보면서 이해해보겠습니다.

javascript에서 변수는 3가지 단계의 생성과정을 걸쳐 생성된다.

  1. 선언 단계

  2. 초기화 단계

  3. 할당 단계

선언 단계(Declaration phase): 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미합니다. 이 변수 객체는 스코프가 참조하는 대상이 된다.

초기화 단계(Initialization phase) : 실행 컨텍스트에 존재하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계입니다. 이 단계에서 할당된 메모리에는 undefined로 초기화된다.

할당 단계(Assignment phase) : 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계이다.

1) var
var 키워드로 선언된 변수는 선언과 초기화가 동시에 진행되는데, 할당하기 전에 호출하면 error가 발생하지 않고 undefined를 반환한다. 이후 변수 할당 단계에 도달하면 값이 할당된다.

var myName;

console.log(myName); // undefined

myName = "taenami";

첫 번째 줄에서, 선언 단계 및 초기화 단계가 동시에 진행되었다.
두 번째 줄에서, 선언, 초기화 단계가 진행되었기 때문에, name이라는 변수는 undefined가 나오게 된 것을 볼 수 있고,
마지막 줄에서, myName의 값이 할당된다.

2) let

let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 나누어서 진행된다.

스코프에 변수를 등록(선언단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어진다. 그렇기 때문에, 초기화 이전에 변수에 접근하면 참조 에러(Reference Error)가 발생한다.

console.log(myName); // Reference Error, TDZ구간

let myName; // 초기화 단계
console.log(myName); // undefined

myName = 'taenami'; // 할당 단계
console.log(myName); // taenami
let age = 10; // 전역 변수

{
  console.log(age); // Reference Error
  let age = 29; // 지역 변수
}

위 예제에서는 let으로 선언한 변수는 호이스팅이 된다는 것을 알려주고 있다.

만약 호이스팅이 되지 않았다면 전역변수의 값인 10을 출력이 되었겠지만, 지역 변수 age도 해당 스코프에서 호이스팅 되고, 코드 블록의 시작점부터, 초기화가 이루어지는 지점까지의 TDZ에 빠지게 되어 위와 같은 에러가 발생한다.

3) const

const는 재할당 및 재선언이 금지된다.
그렇기 때문에, const 키워드로 선언된 변수는 선언 및 할당을 동시에 해야 한다.

참조: https://velog.io/@sangwoo/Javascript-var-let-const-ke1d4ysq
https://taenami.tistory.com/m/87

0개의 댓글