var, let, const의 차이


var

var은 ES5까지 자바스크립트에서 모든 선언을 담당했던 키워드였다.
근데 var은 참 많은 문제점들을 보유하고 있었다고 한다.

그럼 var 키워드의 특징들에는 무엇이 있는지 알아보자.

  1. 함수레벨 스코프(Function-Level-Scope)

    기본적으로 var은 **함수레벨스코프(Function-Level-Scope)**로, 선언된 함수 안에서만 해당 변수를 사용할 수 있도록 한다. 즉, 함수의 코드블록 범위 까지만을 스코프로 인정하는 것이다.

    1
    2
    3
    4
    5
    6
    7
    8
    function test() {
    for (var i = 0; i < 5; i++) {
    continue;
    }
    console.log(i); // 5
    }
    // 근데 함수 밖에서 쓰면 ?
    console.log(i); // ReferenceError: i is not defined

    ⇒ ⚠️ 만약 함수 밖에 전역적으로 var 선언을 했다면, 이는 전역변수가 된다. 따라서 var를 잘못 사용하면 전역변수의 오남용을 초래할 수 있다.

  2. 재선언이 가능하다.

    아래와 같이 변수의 재선언이 가능하기 때문에, 변수 명을 헷갈려 실수로 같은 변수명을 사용하는 등의 오류 발생을 초래할 수 있다.

    1
    2
    3
    var name = 'hoon';
    var name = 'joo';
    console.log(name); // 아무 오류도 발생하지 않고 joo가 출력된다.
  3. 변수를 호이스팅 한다.

    아래에서 호이스팅에 대해 조금 더 자세히 다룰 것이다.
    우선, var은 호이스팅이 되기 때문에 변수를 선언하기 전에 console.log()를 찍어도 에러가 나지 않는다.

    1
    2
    console.log(name); // undefined
    var name = 'hoon';

    ⇒ 하지만 letconst는 위와 같은 코드를 실행시켰을 때 undefined가 아닌 ReferenceError: i is not defined 등의 결과가 나타난다.

스코프?

한 마디로, 변수에 접근할 수 있는 범위를 의미한다.

  1. 전역 스코프

    ⇒ 전역적으로 선언된 변수는 전역 스코프에 해당한다. 따라서 어디서든지 변수에 접근하여 이를 활용할 수 있다.

  2. 지역 스코프

    ⇒ 지역 스코프는 특정 지역(범위)에서만 해당 변수를 접근할 수 있다.


🎣 호이스팅

호이스팅은 끌어올리다

쉽게 말해 “감아올리다”라는 의미다.
호이스팅은 모든 선언문들을 해당 선언문이 적용받은 스코프의 최상단으로 옮겨진 것처럼 작동하도록 한다.
즉, 스코프의 최상단으로 해당 선언문을 끌어올리는 것이다.

호이스팅을 설명하기에 앞 서, 기본적으로 변수가 생성되는 과정은 선언 → 초기화 → 할당과 같다.

  1. 선언단계 (Declaration Phase)

    변수 객체에 변수가 등록된다.

  2. 초기화 단계 (Initialization Phase)

    해당 변수를 메모리에 할당한다. 그리고 변수는 undefined로 초기화 된다.

    1
    2
    // 선언 + 초기화
    var name;
  3. 할당 단계 (Assignment Phase)

    undefined로 초기화된 변수에 원하는 값을 할당한다.

    1
    2
    3
    4
    5
    // 선언 + 초기화
    var name; // undefined
    // 할당
    name = 'hoon';
    console.log(name); // hoon

호이스팅과 변수 생성 과정의 차이에 따라 아래와 같은 차이점들이 나타난다.

  • var

    var의 경우에는 생성과 동시에 초기화가 이루어진다.
    따라서 아래와 같이 console.log(name)만으로도 생성 + 초기화가 이루어진다.

    1
    2
    3
    4
    5
    6
    console.log(name); // undefined

    var name;
    console.log(name); // undefined
    name = 'hoon';
    console.log(name); // hoon
  • let

    하지만 let의 경우에는 생성과 초기화의 과정이 분리되어 있다.
    따라서 아래와 같이 초기화를 하기 전에 변수를 사용하려고 하면 에러가 난다.

    1
    2
    console.log(name); // ReferenceError: name is not defined
    let name;

ES6 : let과 const의 등장

ES6의 등장

ES6 에서 부터 letconst가 등장했다.
이 둘은 var과 어떻게 다르며, 또 letconst는 서로 어떻게 다를까?

함수레벨 스코프 vs 블록레벨 스코프

letconst블록레벨 스코프다. 즉, 변수가 특정한 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언됐다면, 이 코드 블록 내에서만 변수에 접근할 수 있다.

1
2
3
4
5
// 그래서 아래와 같이 for문 안에서 선언된 let은 for문 밖에서 접근할 수 없다.
for (let i = 0; i < 5; i++) {
continue;
}
console.log(i); // ReferenceError: i is not defined

재선언과 재할당

letconstvar과 달리 재선언이 절대 불가능하다.

하지만, 그럼에도 letconst에는 차이점이 있다.

  1. let은 재할당이 가능하다.

    1
    2
    3
    let name = 'hoon';
    name = 'joo';
    console.log(name); // joo
  2. const는 재할당마저도 불가능하다.

    1
    2
    3
    const name = 'hoon';
    name = 'joo';
    console.log(name); // 오류 발생 TypeError: "name" is read-only

Author

Hoonjoo

Posted on

2022-01-06

Updated on

2022-02-07

Licensed under

Comments