ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • var, let, const의 특징과 차이점
    백수의 개발/웹 2021. 8. 11. 00:31

    JS에서는 변수를 선언하는 방식으로 var, let, const가 있다.

    이 세가지의 변수 선언 방법의 특징과 차이를 한번 알아보자.

     

    1. var

    var는 함수 레벨 스코프(function-level-scope)이고.

    var로 선언한 경우 호이스팅(hoisting)으로 인해 함수 내부라면 어디서든 접근이 된다.

     

    function fn() {
    	console.log(varValue); // undefined
    	var varValue = 100;
    	console.log(varValue); // 100
    }
    
    // hoising
    function fn() {
    	var varValue;
    	console.log(varValue); // undefined
    	varValue = 100;
    	console.log(varValue); // 100
    }

    아래 코드를 보면 함수 레벨 스코프로 함부 실행 내부에서 선언된 경우 반복문 밖에서도 접근이 되는 것을 알 수 있다.

    그러나 함수 밖으로 나오게되면 접근할 수 없다.

    function fnFor () {
      for(var i=0; i<10; i++) {
        console.log(`i : ${i}`);
      }
      console.log(`var i : ${i}`); // var i : 10
    }
    fnFor()
    console.log(`fnFor : ${i}`)  // ReferenceError: i is not defined
    
    // hoisting
    function fnFor () {
      var i;
      for(i=0; i<10; i++) {
        console.log(`i : ${i}`);
      }
      console.log(`var i : ${i}`); // var i : 10
    }

    이아 함께 var는 아래와 같이 여려번의 변수선언을 할 수 있다.

    var varValue = 10;
    console.log(`varValue : ${varValue}`); // varValue : 10
    
    var varValue = 'abcd';
    console.log(`varValue : ${varValue}`); // varValue : abcd

    그렇기 때문에 동일한 변수명으로 재선언이 되어 예상치 못한 버그가 발생할 수 있다.

    var는 최대한 사용하지 말자!

     

    2. let과 const

    let과 const는 블록 레벨 스코프(block-level-scope)이고.

    호이스팅(hoisting) 되지 않는다.

    // hoisting이 되지 않는다.
    function fn() {
    	console.log(letValue); // ReferenceError: Cannot access 'letValue' before 
    	let letValue = 100;
    	console.log(letValue);
    }
    // hoisting되지 않는다.
    function fnFor () {
      for(let i=0; i<10; i++) {
        console.log(`i : ${i}`);
      }
      console.log(`let i : ${i}`); // ReferenceError: i is not defined
    }

    그리고 let과 const 모두 변수의 재선언이 불가능하다.

    let letValue = 10;
    console.log(`letValue : ${letValue}`); // letValue : 10
    
    let letValue = 'abcd'; // SyntaxError: Identifier 'letValue' has already been declared
    console.log(`letValue : ${letValue}`);

     const가 let과 다른 하나는 재할당이 불가능하다는 것이다.

    let letValue = 10;
    console.log(`letValue : ${letValue}`); // letValue : 10
    
    letValue = 'abcd';
    console.log(`letValue : ${letValue}`); // letValue : abcd
    const constValue = 10;
    console.log(`constValue : ${constValue}`); // constValue : 10
    
    constValue = 'abcd'; // TypeError: Assignment to constant variable.
    console.log(`constValue : ${constValue}`);

    단, const에 할당된 값이 object인 경우 내부 값은 변경이 가능하다.

    const constValue = {
    	innerValue: 10
    };
    console.log(`constValue.innerValue : ${constValue.innerValue}`);
    // constValue.innerValue : 10
    
    constValue.innerValue = 'abcd';
    console.log(`constValue.innerValue : ${constValue.innerValue}`);
    // constValue.innerValue : abcd

    이 또한 Object의 freeze를 통해 일부 막을 수는 있다.

    const constValue = {
    	innerValue: 10
    };
    Object.freeze(constValue);
    console.log(`constValue : ${constValue.innerValue}`);
    // constValue.innerValue : 10
    
    constValue.innerValue = 'abcd';
    console.log(`constValue : ${constValue.innerValue}`); // error가 발생하지는 않음
    // constValue.innerValue : 10

    그러나 또 내부의 object에 대해서도 중첩되어있다면 이 또한 내부 값이 변경된다.

    const constValue = {
      innerValue: {
        innerValue: 10
      }
    };
    Object.freeze(constValue);
    console.log(`constValue.innerValue.innerValue : ${constValue.innerValue.innerValue}`);
    // constValue.innerValue.innerValue : 10
    
    constValue.innerValue.innerValue = 'abcd';
    console.log(`constValue.innerValue.innerValue : ${constValue.innerValue.innerValue}`);
    // constValue.innerValue.innerValue : abcd

    결론

    가능한 var을 통한 변수선언은 피하고, let과 const를 사용해라.

    또한 필수적으로 재할당이 일어나는 데이터들에 대해서만 let을 통해 변수선언을 해주고,

    의도하지 않은 값의 변경이 일어나지 않도록 이외의 데이터는 const를 통해 변수선언을 해주자. 

     

    댓글

Designed by Tistory.