Modern Javascipt (const, let, var)

신윤철·2022년 3월 14일
0

JS

목록 보기
1/4
post-thumbnail

const, let을 사용하는 이유

블록 레벨 스코프, 함수 레벨 스코프, 호이스팅 등의 차이를 알아보기 이전에 코드를 작성할 때 왜 const와 let을 사용하는지 배워보겠습니다.

const를 사용하는 이유

결론부터 말하자면 대부분의 경우에 const를 사용하는 것이 좋습니다.

const는 가장 많은 제약이 있고 이는 코드를 쉽게 이해할 수 있게 만듭니다.

왜 가장 기능이 적은 const가 코드를 쉽게 만든다는 것 일까요?

한번 값을 할당하면 재할당이 불가능하다는 const의 성질은 코드를 훑어보는 개발자가 const로 선언된 변수를 신경쓰지 않도록 만듭니다.

두가지 예제를 살펴보겠습니다.

// var 선언
var salePercent = 0.2;
var totalPrice = 100 - (100 * salePercent);
// 200행의 코드 생략
return `총 구매 금액은 ${totalPrice}입니다.`;
// const 선언
const salePercent = 0.2;
const totalPrice = 100 - (100 * salePercent);
// 200행의 코드 생략
return `총 구매 금액은 ${totalPrice}입니다.`;

만약 var로 선언된 코드를 읽는다면 생략된 200줄의 코드에서 salePercent가 변경되는 부분이 있는지 꼼꼼히 읽어봐야합니다.

하지만 salePercent가 const로 선언된다면 200줄의 코드에서 salePercent가 변경될 일이 없기 때문에 해당 변수는 신경쓰지 않아도 됩니다.

이러한 가독성과 코드의 이해력을 높히기 위해 재할당이 필요없는 변수는 const를 사용하길 권장합니다.

const 사용시 주의사항

앞서 const는 재할당이 불가능한 변수라고 설명했습니다.
하지만 const에 할당된 값이 불변값이 되는 것은 아닙니다.

모순되는 말처럼 들릴 수 있지만 이전 데이터 할당 포스트를 보면 이해를 도울 수 있습니다.

기본적으로 자바스크립트는 배열이나 객체를 할당할때 객체나 배열의 프로퍼티의 주소를 변수에 할당하므로
const로 선언한 변수 자체를 변경하는 것이 아닌 변수의 주소와 연결된 프로퍼티는 변경 가능한 것입니다.

조금 어려운 부분인데, 요약하자면 const에 배열 또는 객체를 선언할 경우 내부 프로퍼티는 변경 가능하기 때문에 const값을 확신할 수 없다는 것 입니다.

let을 사용하는 이유

앞서 변수를 다룰 때는 재할당을 피하는 것이 낫다고 배웠습니다. 하지만 재할당이 필요할 경우 let을 사용해야 합니다.

var이 아닌 let을 사용하는 이유는 무엇일까요?

var은 함수 레벨 스코프, let은 블록 레벨 스코프이기 때문입니다. (스코프에 관한 글)

왜 블록 레벨 스코프를 사용해야 하는지 예제를 통해 알아보겠습니다.

//var 사용
const item = {
    inventory: 3,
    price: 3,
    salePrice: 2,
    saleInventory: 0,
  };

function getLowestPrice(item) {
    var count = item.inventory;
    var price = item.price;
  
    if (item.salePrice) {
      var count = item.saleInventory;
      if (count > 0) {
        price = item.salePrice;
      }
    }
  
    if (count) {
      return price;
    }
  
    return 0;
  }

의도대로 함수 결과를 출력한다면 saleInventory가 0이므로 정상적인 가격 Price(2)를 출력해야 합니다.

하지만 var는 함수 레벨 스코프이므로 var count = item.inventory;의 count를 if문 내의 var count = item.saleInventory;에서 재할당합니다.

때문에 if (count) { return price; }에서 count를 0으로 인식하여 return 0을 반환한 것 입니다.

//let 사용
const item = {
    inventory: 3,
    price: 3,
    salePrice: 2,
    saleInventory: 0,
  };

function getLowestPrice(item) {
    let count = item.inventory;
    let price = item.price;
  
    if (item.salePrice) {
      let count = item.saleInventory;
      if (count > 0) {
        price = item.salePrice;
      }
    }
  
    if (count) {
      return price;
    }
  
    return 0;
  }

하지만 let을 사용하면 각각의 변수를 블록 레벨 스코프로 인식하여 let count = item.inventory;의 count와 if (item.salePrice) 내의 count와 다른 변수로 인식하여 앞서 생긴 버그를 해결합니다.

블록 레벨 스코프에서는 내부 블록에서 외부 블록의 변수를 사용할 수 있지만, 외부 블록에서는 내부 블록의 변수에 접근할 수 없습니다.

이 외에도 let은 유효범위 내에서 같은 변수명을 재사용할 수 없다는 장점도 있습니다.

const, let, var의 차이점

앞서 const와 let을 사용하는 이유에서 몇몇 차이점을 언급했지만 다시 정리해보겠습니다.

  1. var은 함수 레벨 스코프이고 const,let은 블록 레벨 스코프입니다.

  2. var은 유효범위 내에서 이미 선언한 변수명과 같은 변수를 선언할 수 있지만, let과 const는 이미 존재하는 변수와 똑같은 변수를 선언할 수 없습니다.

  3. var와 let은 변수 선언시 초기 값을 할당하지 않아도 되지만 const는 항상 초기값을 할당하여 선언해야합니다.

  4. var은 선언하고 값을 할당하기 전에 사용하면 undefined값을 반환하지만, const, let은 선언하고 값을 할당하기 전에 사용하면 에러를 발생시킵니다.(TDZ)

  5. var, let은 할당된 값을 변경할 수 있지만 const는 할당된 값을 변경할 수 없습니다.(하지만 const가 배열또는 객체일 경우 내부 프로퍼티는 변경할 수 있습니다.)

⁂ TDZ : Temporal Dead Zone의 약자로 var과 달리 let과 const는 호이스팅 시 자동으로 부여되는 초기값이 없어 TDZ구간에서 let과 const로 선언된 변수를 사용시 에러가 발생됩니다.

정리하자면 최대한 const변수를 사용하고 재할당이 필요한 경우 let을 사용합시다! (var은 안됩니다(˘・_・˘))

profile
기본을 탄탄하게🌳

0개의 댓글