본문 바로가기
개발 공부/JavaScript + jQuery

[JavaScript] var, let, const 차이점 / 호이스팅

by sngynhy 2022. 1. 27.

1. JavaScript 변수 선언 방식

JavaScript는 변수 선언 시 Data Type을 명시하지 않는다.

즉, 모든 타입의 값을 대입 가능하다.

 

var 변수

  • 선언된 함수의 전 영역에서 사용 가능 - function scope
  • 동일한 이름의 변수를 여러 개 선언 가능
  • var로 선언한 변수는 선언 전에 사용 가능
  • 변수 선언 시 초기값을 할당하지 않아도 되며, 이후 값을 다시 할당할 수 있음
  • 로깅 시 편리하지만 코드량이 많아 질 경우 어디에서 어떻게 사용 될지 파악이 힘들고 값이 바뀔 우려가 있음
var num = 20;
var address = “서울시 종로구”;
var num1, num2, num3;
var num1, num2=20, num3=40;
var ageList = [10, 20, 30, 40, 50];

var name = "mon cher";
var name = "leon";

let / const 변수

  • 선언된 block 내에서만 사용 가능 - block scope
  • 같은 scope에 동일한 이름의 변수 선언 불가능 (에러 발생)
  • let과 const로 선언한 변수는 선언 전에 사용 불가능 (에러 발생)
  • let : 변수 선언 시 초기값을 할당하지 않아도 되며, 이후 값을 다시 할당할 수 있음
    let num = 20;
    let address = “서울시 종로구”;
    let num1, num2, num3;
    let num1, num2=20, num3=40;
    let ageList = [10, 20, 30, 40, 50];
    
    let name = "mon cher";
    let name = "leon"; // 에러 발생 Uncaught SyntaxError: Identifier 'name' has already been declared
  •  const : 변수 선언 시 반드시 초기값 할당해줘야 하며, 이후 값을 변경할 수 없음 (JAVA의 상수과 같은 역할)
    (단, 객체 안에 프로퍼티는 변경 가능!
    만일 const 변수에 객체를 할당했을 경우 const 변수가 가리키고 있는 객체 자체를 변경하는 것은 불가능하지만
    해당 객체 내의 프로퍼티는 변경이 가능하다.)
    const obj = { first: 1 };
    obj = 1; // 에러 발생 Uncaught TypeError: Assignment to constant variable.
    
    // 에러 발생하지 않음.
    obj.first = 2;
    obj.second = 2;
    delete obj.first;​
     위와 같이 const 변수가 가리키는 값 자체 변경 시 에러가 발생하지만, 객체 내의 프로퍼티 추가/변경/삭제는 가능하며, 만약 객체의 프로퍼티도 변경되지 않게 객체를 선언하고 싶다면 Object.freeze() 메소를 사용하면 된다.

2. 호이스팅 (Hoisting)

호이스팅이란?

var 선언문이나 function 선언문 등을 해당 scope의 선두로 옮긴 것처럼 동작하는 특성을 말한다.

JavaScript 함수는 실행되기 전에 함수 안에 필요한 변수 값들을 모두 모아서 유효 범위의 최상단에 선언한다.

  • JavaScript parser가 함수 실행 전 해당 함수를 한번 훑는다.
  • 함수 안에 존재하는 변수 및 함수 선언에 대한 정보를 기억하고 있다가 실행시킨다.
  • var, let, const, function, class 등의 선언 키워드들은 모두 호이스팅된다.
  • scope : 함수 block 안에서만 유효

즉, 함수 내에서 필요한 값들을 끌어 올리는 것!

실제로 코드가 끌어올려지는 것은 아니며, parser 내부적으로 끌어올려서 처리한다.

실제 메모리에는 변화가 없다.

 

var의 경우 호이스팅 되면서 초기값이 없으면 자동으로 undefined를 초기값으로 하여 메모리를 할당하기 때문에

선언 전에 해당 변수를 사용해도 에러가 발생하지 않는다.

console.log(name); // undefined
var name;

 

let과 const의 경우 호이스팅 되면서 초기값이 없다면 var와 같이 자동으로 초기값을 할당하지 않는다.

따라서 값이 할당되기 전까지 메모리를 할당하지 않기 때문에 변수 선언 전에 사용하게 되면 에러가 발생한다.

(애초에 const의 경우 선언 시 초기값을 할당하지 않으면 문법 에러 발생!)

이처럼 let 변수가 선언되고 해당 변수에 값이 할당되기 전까지를 일시적 사각지대(Temporal Dead Zone; TDZ)라고 한다.

console.log(name); // 에러 발생 Uncaught ReferenceError: num is not defined
let name = "leon";
console.log(name); // leon

 

※ 참고

https://velog.io/@bathingape/JavaScript-var-let-const-%EC%B0%A8%EC%9D%B4%EC%A0%90

https://medium.com/@su_bak/javascript-var-let-const%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90-9fab5c264c9c