var const let 의 차이

해준박·2024년 3월 7일
0

이번 주 강의를 들으면서 let const 차이를 배우면서, 예전에 기술면접을 공부할 때 호이스팅을 생각하면서 정리를 하였습니다.


var

자바스크립트가 ES6 이전 버전에는 var을 사용하였습니다.

특징

  • var 변수가 함수 외부에서 선언될 때는 전역, 함수 내부에서 선언될 때는 해당 함수 내에서만 사용하고 접근 할 수 있다.
var tester = "hey hi";
    
function newFunction() {
	  var hello = "hello";
}
console.log(hello); // error: hello is not defined

  • var변수는 재선언되고, 업데이트가 가능
var greeter = "hey hi";
var greeter = "say Hello instead";

console.log(greeter); // say Hello instead
var greeter = "hey hi";
greeter = "say Hello instead2";
console.log(greeter); // say Hello instead2

위 와 같이 코드를 짜도 에러가 발생하지 않습니다.


var의 문제점

var greeter = "hey hi";
var times = 4;

if (times > 3) {
  var greeter = "say Hello instead"; 
}

console.log(greeter) // "say Hello instead"

time > 3가 true를 반환하기 때문에 greeter는 "say Hello instead"로 재정의됩니다. 의도적으로 재정의한 것이라면 괜찮겠지만, 변수 greeter가 이미 정의되어 있다는 사실을 인식하지 못한 경우에는 문제가 됩니다.

또한, 다른 코드의 부분에서 greeter가 사용되어진다면 원하는 출력 결과를 얻을 수 없는 경우가 생기게됩니다.


let

ES6에서 var선언에 대한 개선을 반영한 변수 선언

특징

  • let으로 선언된 변수는 해당 블록 내에서만 사용가능합니다. 블록은 중괄호{}로 바인딩된 코드들 입니다. 전역 범위에서 선언되었을 경우 코드 어디에서나 사용가능합니다.
let greeting = "say Hi";
let times = 4;

if (times > 3) {
  let hello = "say Hello instead";
  console.log(hello); // "say Hello instead"
  console.log(greeting); // say hi
}
console.log(hello); // hello is not defined

  • let은 업데이트는 가능하지만 재선언은 불가능합니다.
let greeting = "say Hi";
greeting = "say Hello instead";
console.log(greeting); // say Hello instead
let greeting = "say Hi";
let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared

만약 let변수가 다른 블록 즉, let으로 선언된 동일한 변수가 다른 범위 내에서 정의된다면 에러가 발생하지 않습니다.

let greeting = "say Hi";
if (true) {
  let greeting = "say Hello instead";
  console.log(greeting); // "say Hello instead"
}
console.log(greeting); // "say Hi"

const

요즘 코드는 거의 const입니다. const는 일정한 상수 값을 유지합니다.

특징

  • let 마찬가지로 블록 범위 내에서 접근 가능합니다. 전역으로 선언할 경우 모든 곳에서 접근 가능합니다.
  • const는 업데이트도, 재선언도 불가능하다
const greeting = "say Hi";
greeting = "say Hello instead";// error: Assignment to constant variable. 
const greeting = "say Hi";
const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared

따라서 const는 선언과 동시에 초기화가되어야 합니다.

  • 배열이나 객체는 참조타입이기에 객체의 요소나 속성은 변경이 가능합니다.
const arr = [1, 2, 3];
arr.push(4);
console.log(arr); // [1, 2, 3, 4]

const obj = { a: 1, b: 2 };
obj.c = 3;
obj.a = 4;
console.log(obj); // { a: 4, b: 2, c: 3 }

호이스팅

호이스팅이란?
자바스크립트 코드가 실행될 때 실행 컨텍스트 환경에서 "생성 단계"에서 발생합니다.
호이스팅은 코드가 실행하기 전 변수선언/함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상 즉, 변수 및 함수 선언을 먼저 하는 과정입니다.

3-2-1. 생성 단계

  • 실행 컨텍스트 생성
  • 선언문만 실행해서 Environment Record에 기록 (실행 컨텍스트에 저장) -> 호이스팅

3-2-2. 실행 단계

  • 선언문 외 나머지 코드 순차적 실행
  • 실행 컨텍스트에 저장된 정보 참조 또는 업데이트
    이러한 단계들을 거쳐서 실행 컨텍스트를 구성한다.

이렇게 알게된 호이스팅으로 var let const의 호이스팅에 대해 알아보았습니다.

var의 호이스팅

console.log(greeter); // undefined
var greeter = "say hello"

위 코드가 실행되면 undefined가 뜹니다

실행컨텍스트의 레코드에서는 아래와 같은 단계가 이루어집니다

// 생성단계
var greeter; // 1. 선언
greeter = undefined // 2.초기화
console.log(greeter) // undefined
// 실행단계
greeter = "say hello" // 3. 할당

var은 호이스팅에서 생성단계에서 선언과 초기화가 동시에 이루어집니다.

let과 const의 호이스팅

console.log(greeter); // greeter가 선언은 되었지만 초기화 x -> TDZ
let greeter = "say hello"; // 초기화 -> 할당

// ReferenceError: Cannot access 'greeter' before initialization

console.log(greeter); // TDZ
const greeter = "say hello"; // 선언 -> 초기화 -> 할당
// ReferenceError: Cannot access 'greeter' before initialization

const let은 var과 다르게 변수에 값이 할당되기 전에 접근 할 경우 참조에러가 발생합니다.

이를 TDZ(Temporal Dead Zone)일시적 사각지대 라고 합니다 -> 선언 이전에 식별자를 참조할 수 없는 구역

TDZ로 우리는 코드의 실수를 줄일수 있다는 이점이 있다고합니다.

let, const 키워드로 변수를 선언한 경우, 값을 undefined로 선언하지 않기 때문에 할당 문 직전까지 변수에 아무런 값이 담겨 있지 않아, 접근하고자 하면 error가 발생합니다. 선언 라인 이전에 변수를 참조할 수 없다는 것을 의미합니다.

참고사이트
[JS] 실행 컨텍스트(Execution Context)
Var, Let, Const의 차이점은?
[JavaScript] 호이스팅(Hoisting)

profile
기록하기

0개의 댓글