var, let, const

Leo·2023년 7월 1일
0

FrontEnd

목록 보기
23/26
post-thumbnail

var, let, const의 차이점

1. 변수 선언 방식

var, let, const 는 javaScript의 변수 선언 방식이다.
같은 기능을 하는 것 같지만 조금씩 다른 기능을 하고 있다

var

중복 선언 가능, 재할당 가능

var title = 'book';
console.log(title); // book

var title = 'movie';
console.log(title); //movie

title = 'music';
console.log(title);//music
  • var는 원조 변수 선언 방식으로, 위 코드와 같이 선언한 변수가 동일한 이름으로 중복 선언이 가능하다. 즉, 마지막에 할당된 값이 최종 변수에 저장된다.
  • 변수를 유연하게 사용할 수 있지만, 기존에 선언해둔 변수의 존재를 잊고 재선언 하는 경우 문제가 발생할 수 있다.
  • 특히 간단한 코드가 아닌, 길고 복잡한 코드에서 같은 이름의 변수가 여러번 선언되어 사용되면 어떤 부분에서 값이 변경되고 문제가 발생하는지 파악하기 힘들다.

이를 보완하기 위해 ES6 부터 추가된 변수 선언 방식이 let 과 const 이다.

let

중복 선언 불가, 재할당 가능

let title = 'book';
console.log(title); // book

let title = 'movie';
console.log(title); 
//Uncaught SyntaxError: Identifier 'title' has already been declared

title = 'music';
console.log(title);//music
  • let은 var와 달리 중복선언 시, 해당 변수는 이미 선언되었다는 에러 메시지를 뱉는다. 즉, 중복 선언이 불가하다. 하지만 변수에 값을 재할당하는 것은 가능하다.

const

중복 선언 불가, 재할당 불가

const title = 'book';
console.log(title); // book

const title = 'movie';
console.log(title); 
//Uncaught SyntaxError: Identifier 'title' has already been declared

title = 'music';
console.log(title);
//Uncaught TypeError: Assignment to constant variable

let와 const의 차이는 immutable(재할당) 가능 여부이다.
재할당은 가능한 let과 달리 const는 재할당 또한 불가하다.

2. 스코프 (Scope)

유효한 참조 범위가 다르다.

var

함수 레벨 스코프 (function level scope)

function function_level(){
  if(true){
   var a = 123;
   console.log(a); //123 
  }
 console.log(a);
}

function_level(); //123
console.log(a);//ReferenceError: a is not defined
  • 함수 내에서 선언된 변수는 함수 내에서만 유효하고, 함수 내에서는 블록 내외부에 관계없이 유효하다. 함수 외부에서는 참조불가

let / const

블록 레벨 스코프 (block level scope)

function block_level(){
  if(true){
   let a = 123;
   console.log(a); //123
  }

console.log(a); // ReferenceError: a is not defined.
}

console.log(a);// ReferenceError: a is not defined.
  • 함수, if절 외 for, while, try/catch 등 모든 코드블록 ({..}) 내부에서 선언된 변수는 코드 블록 내부에서만 유효함. 블록 외부부터 참조 불가.

3. 호이스팅 방식 (Hoisting)

자바스크립트 함수는 실행되기 전에 함수내 필요한 변수값들을 모두 모아 유효 범위의 최상단에 선언한 것 처럼 동작한다.
이런 방식을 호이스팅이라 한다.

호이스팅 동작 방식

  1. 자바스크립트 parser가 함수 실행 전 해당 함수 전체를 훑는다.
  2. 함수 내 존재하는 변수, 함수 선언에 대한 정보를 기억하고 실행한다.
  3. 유효범위는 함수 블록 {} 내 인데, 필요한 값들을 블록 위의 상단으로 끌어올리는 것이다.
  4. 실제코드가 끌어올려지는 것은 아니고, 자바스크립트 parser내부적으로 끌어올려 처리하는 것이므로 실제 메모리에서는 변화가 없다

var 선언문 호이스팅

console.log(a); //undefined

var a = 123;
console.log(a); //123
  • 변수 a가 선언되기 전에 참조시, 에러가 발생하지 않고 undefined가 출력된다. 이는 코드 실행 전에 자바스크립트 내부에서 미리 a변수를 선언하여 undefined로 초기화를 해두었기 때문이다.

함수선언문 호이스팅

test(); //test

function test(){
  console.log("test");
}
  • 함수 선언문 또한 함수 선언 전 호출시 test를 출력한다.

let / const 선언문 호이스팅

console.log(a); //ReferenceError: a is not defined

let a = 123;
console.log(a); // 123

let의 경우 변수 a가 선언되기 전에 참조하면 에러가 발생한다.

var 변수 선언은 변수 선언과 동시에 초기화가 이루어지지만 let, const 변수는 선언만 해놓고 초기화는 하지 않는다.

코드 실행 과정에서 변수 선언문을 만났을 때, 초기화를 수행한다.
때문에 호이스팅은 발생하였으나 변수의 선언과 초기화 사이에 일시적으로 변수값을 참조할 수 없는 구간인 TDZ(Temporal Dead Zone)에 빠졌기 때문에 보이는 현상이다.

함수 표현식 호이스팅

test(); // error

var test = function() {
  console.log("test");
}

test(); // test
  • 함수 선언이 아닌 함수 표현식에서 마찬가지의 이유로 에러가 발생하는 것을 확인할 수 있다.

정리

❓ 그래서 뭘 쓰는게 좋을까?
재할당이 필요없는 상수와 객체에는 기본적으로 const를 사용하는 것이 좋다. 의도치 않은 재할당을 방지해주기 때문에 안전하다

재할당이 필요한 경우 한정적으로 let을 사용하는 것이 좋다. 단, 이 때의 변수의 스코프는 최대한 좁게 만드는 것이 좋다

0개의 댓글