• let, const

    2022. 8. 27.

    by. JJo 😊

    ES6에 새롭게 등장한 변수 친구들이다! 😁

    기존의 'var'은 유연한 변수 선언 방식이었다. 예를 들어, 변수를 한번 더 선언했음에도 불구하고 에러가 나오지 않는다.

    var age = 28;       //결과 : 28 (초기 변수 선언) 
    age = 18;           //결과 : 18 (변수값 재할당)  
    var age = 'old';    //결과 : 'old' (변수 재선언)

     

    이러한 유연한 점이 편리할 수 있겠으나, 코드량이 많아지거나 다른 사람들과 협업을 하는 과정에서는 파악이 힘들뿐더러 값이 바뀔 가능성이 있다. 그래서 이러한 점을 보완하기 위해 등장한 것이 바로 let과 const이다!

    위의 소스에서 변수 선언 방식을 let으로 바꾸면 다음과 같이 에러가 발생한다.

    let age = 28;
    age = 18;
    let age = 'old'; //SyntaxError: Identifier 'age' has already been declared

    age라는 변수가 이미 선언되어 있다는 오류가 나온다.(const도 마찬가지)

    여기서 알 수 있는 점은 var은 재선언이 가능하지만 let과 const는 재선언을 할 수 없다는 차이점이 있다.

    그렇다면 let과 const의 차이점은 무엇일까? 이 둘의 차이점은 불변(immutable)의 여부이다. let은 변수에 재할당이 가능하지만 const는 재선언, 재할당이 불가능하다!

     

    📌 let

    let meal = 'Bulgogi';
    meal = 'Bibimbap'; //재할당 가능

    📌 const

    const myName = 'NY KIM';
    myName = 'Nana';  //TypeError: Assignment to constant variable

    constant(상수)라는 뜻을 가진 const는 변치 않는 값을 갖는 변수이다. 그러므로 const로 선언한 변수는 값을 재할당할 수 없다. 또한, const 변수는 반.드.시 값이 할당되어 있어야 한다.🤔

    값 없이 선언할 경우 에러를 발생시킨다!

    const a;
    console.log(a); //SyntaxError: Missing initializer in const declaration
    ✨ cosnt변수가 가리키고 있는 개체 자체를 변경하는 것은 불가능하지만, 해당 객체 내의 프로퍼티가 변경되는 것까지 막지는 못한다.

     

    📌 Hoisting

    호이스팅이란, var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성을 의미한다. 자바스크립트는 변수와 함수 선언문을 호이스팅하는데, let으로 선언된 변수를 선언문 이전에 참조하게 되면 참조 에러가 발생한다.

    그 이유는, let과 const의 경우 호이스팅이 되면서 초기값이 없을 경우 var 처럼 자동으로 초기값을 할당하지 않기 때문이다. 값이 할당되지 전까지 메모리를 할당하지 않기 때문에 에러가 발생한다.

     

    👉 변수 생성 3단계

    1. 선언 단계 : 변수를 실행 컨텍스트의 변수 객체에 등록. 변수 객체는 스코프가 참조하는 대상

    2. 초기화 단계 : 변수 객체에 등록된 변수를 위한 메모리 확보 및 undefined로 초기화

    3. 할당 단계 : undefined로 초기화된 변수에 실제 값 할당

    ✨ var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. 즉, 스코프에 변수를 등록하고 메모리에 변수 공간을 확보한 후 undefined로 초기화하는 과정이 한번에 일어나므로, 변수 선언 이전에 변수에 접근해도 에러가 발생하지 않는다. 이때, undefined를 반환한다. 이후 변수 할당문에 도달하면 비소로 값이 할당된다.

    var

    console.log(name); //결과: undefined
    var name = 'eunhye';

    undefined 출력만 할 뿐 문제없이 잘 작동한다.

     

    let/const

    console.log(product); //ReferenceError: Cannot access 'product' before initialization
    console.log(price); //ReferenceError: Cannot access 'price' before initialization
    const product = 'watch';
    let price = 500;

    let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 선언 단계가 먼저 진행되고 변수 선언문에 도달했을 때 초기화 단계가 이루어진다. 그러므로 초기화 이전에 변수에 접근하면 참조 에러가 발생한다. 따라서 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는데, 이 구간을 '일시적 사각지대(TDZ)'라고 한다.

     

    📌 Scope

    Scope는 범위를 나타낸다. 즉, 변수가 어디까지 접근 및 영향을 주는지를 나타낸다.

     

    var

    var는 함수 레벨 스코프이다.

    var level = 10;
    console.log(level); // 10
     
    function levelUp(){
      var level = 30;
      console.log(level); // 30
    }
     
    console.log(level); // 10

    위의 코드에서 마지막에 호출한 level은 전역이기에 10이 출력된다.

    var level = 10; 
    console.log(level); // 10
     
    if (true) {
      var level = 30;
      console.log(level); // 30
    }
     
    console.log(level); // 30

    if문은 함수가 아니고 블럭이기 때문에 if 블럭문 내에서 재할당된 값이 출력이 된다.

     

    let/const

    let과 const는 블럭 레벨{ } 스코프이다.

    let level = 10;
    console.log(level); // 10
     
    function levelUp(){
      let level = 30;
      console.log(level); // 30
    }
     
    console.log(level); // 10
    let level = 10; 
    console.log(level); // 10
     
    if (true) {
        let level = 30;
        console.log(level); // 30
    }
     
    console.log(level); // 10

    let은 블럭 스코프를 갖기 때문에 블럭이 닫히는 시점에서는 let의 유효범위가 끝나게 된다.

    var me = 28;
    let sister = 24;
     
    console.log('me : '+me, '| sister : '+sister);    // me : 28 | sister : 24
     
    if(2021>2020){
      var me = 29;
      let sister = 25;
      console.log('me : '+me, '| sister : '+sister);  // me : 29 | sister : 25
    }
     
    console.log('me : '+me, '| sister : '+sister);    // me : 29 | sister : 24 (???)
     
    function goBack(){
      var me = 12;
      let sister = 8;
      console.log('me : '+me, '| sister : '+sister);   // me : 12 | sister : 8
    }
     
    goBack();
    console.log('me : '+me, '| sister : '+sister);     // me : 29 | sister : 24 (???)

    📌  그럼 언제 let을 쓰고, 언제 const를 쓰면 될까?

    변수 선언 시 기본적으로 cosnt를 사용하고 재할당이 필요한 경우에는 let을 한정적으로 사용한다.

    • ES6를 사용할 경우에는 var 사용을 자제한다.
    • 재할당이 필요한 경우에는 let을 사용하며 변수의 스코프는 최대한 좁게 만든다.
    • 변경되지 않는 원시 값과 객체에는 const를 사용한다.
    728x90

    'Javascript' 카테고리의 다른 글

    데이터 불변성  (0) 2022.09.02
    DOMContentLoaded VS load  (0) 2022.09.02
    ES6 Classes  (0) 2022.09.01
    전개연산자  (0) 2022.08.28
    구조 분해 할당  (0) 2022.08.28

    댓글