let, const, var

JJ_Dean·2023년 1월 1일

JavaScript

목록 보기
3/3
post-thumbnail

변수 선언 단계

let, const, var 는 자바스크립트에서 변수를 선언하는 방법이다.
자바스크립트에서 변수의 선언은

선언 ➡ 초기화

단계를 거친다.

  • 선언 : 변수명으로 자바스크립트 엔진에 변수의 존재를 알린다.
  • 초기화 : 메모리 공간 확보하고, 암묵적으로 undefined를 할당하여 초기화한다.

호이스팅

자바스크립트 엔진은 소스코드를 순차적으로 실행하기 전에, 변수 선언을 포함한 모든 선언문을 찾아서 먼저 실행한다. 이때 변수 선언이 어디에 위치하고 있든 상관없이 다른 코드들 보다 먼저 실행되는 특징을 호이스팅이라고 한다.


비교해보자

ES6 문법 이전에는 var, 이후에는 let과 const를 사용한다.

var

var 의 특징은 다음과 같다.

⭐️ 변수 중복 선언이 가능하다.

var로 선언한 변수를 또 다시 var로 선언할 수 있다.

var ingredient = 'tomato';
var ingredient = 'onion';

console.log(ingredient); // onion

⭐️ 함수 레벨 스코프로 인해 함수 외부에서 선언한 변수는 모두 전역 변수로 된다.

var ingredient = 'tomato';

if (true) {
  var ingredient = 'onion;
}

console.log(ingredient); // onion

⭐️ 변수 선언문 이전에 변수를 참조하면 언제나 undefined를 반환한다.

var 로 선언된 변수는 선언 단계초기화 단계즉시 진행된다.
즉 런타임 이전에 선언과 초기화가 완료된다.

console.log(ingredient); // undefined

var ingredient = 'tomato';
console.log(ingredient); // tomato

var의 특징은 유연한 개발에 도움을 줄 수 있었지만 난해하고, 코드가 길어지면 예측할 수 없는 버그가 생기는 등 문제가 있었다.

이런 문제를 해결하고자 ES6 부터 let 과 const가 생겼다.

let과 const

let과 const 특징은 다음과 같다.

⭐️ 변수 중복 선언 불가

[ let ]
재할당은 가능하지만 var처럼 재선언은 안된다.

let ingredient = 'tomato';
console.log(ingredient); // tomato

let ingredient = 'onion'; // Uncaught SyntaxError: Identifier 'name' has already been declared

ingredient = 'onion';

console.log(ingredient); // onion

[ const ]
원시값의 재할당, 재선언은 모두 불가능하다.

const ingredient = 'tomato';
ingredient = 'onion'; // Uncaught TypeError: Assignment to constant variable.

객체의 재할당은 가능하다. 물론 재선언은 안된다.

const ingredient = {
  first: 'tomato',
}
ingredient.first = 'onion'

console.log(ingredient) // { first: "onion" }

⭐️ 블록 레벨 스코프

let과 const 로 선언된 변수는 모두 코드 블록을 지역 스코프로 인정한다.

let ingredient = 'tomato';

if (true) {
  let ingredient = 'onion;
}

console.log(ingredient); // tomato

⭐️ 호이스팅

[ let ]
let 으로 선언된 변수는 선언 단계초기화 단계분리되어 진행된다.
즉슨 런타임 전에 자바스크립트 엔진에 의해 선언 단계로 실행되지만,
초기화 단계가 진행되지 않은 상태이기 때문에 변수에 접근하면 참조 에러 (레퍼런스 에러)가 난다.

// 선언 단계는 진행됐지만 초기화 단계 진행 X
console.log(ingredient); // ReferenceError: Cannot access 'ingredient' before initialization

let ingredient = 'tomato';

// 초기화 단계 진행 후
console.log(ingredient); // tomato

let 으로 선언한 변수는 스코프의 시작 지점부터 초기화 단계 시작 지점까지 변수를 참조하 수 없는 일시적 사각지대(Temporal Dead Zone: TDZ)가 존재한다.
까다롭지만 var에 비해 헷갈리지 않고 변수를 사용할 수 있게 한다.

[ const ]
const 로 선언된 변수도 선언 단계초기화 단계분리되어 진행된다.

console.log(ingredient); // ReferenceError: Cannot access 'ingredient' before initialization

const ingredient = 'tomato';

let, const 으로 선언한 변수는 런타임 이전에 선언되어 엔진에 존재하는 상태이지만 초기화가 진행되지 않았다.

무엇을 쓸까

변수의 스코프는 최대한 좁게 만드는 것이 권장된다. 따라서 var 보다는 let과 const를 사용하고, 변경하지 않는 값(상수)이라면 let 보다는 const 키워드를 사용하는 것이 안전하다.

profile
공부하고 내 것으로 만들자.

0개의 댓글