ES6(ES2015) 에서는 var 이와에 const 와 let을 이용하여 변수를 선언을 할수 있게 되었습니다
대부분 모던 자바스크립트 코드를 보면 var 보다는 const,let 을 이용하여 변수 할당이 되어 있는것을 확인하실수있는데 3개의 변수 할당이 어떻게 다른 특징이 있는지 살펴보겠습니다.
ES6 이전에는 변수를 할당하는 방법은 var를 이용하여 변수를 할당하는 방법이 있었습니다.
어휘적 유효범위 (lexical scope)
프로그레밍에서는 scope 는 해당 값의 범위라는 의미를 가집니다. var의 특징을 살펴 보겠습니다.
간단한 조건문을 이용하여 아래 코드가 실행을 유추해 봅시다.
var dog = 'Ralf';
if (true) {
var dog = 'Skip';
}
console.log(dog);
너무쉽죠ㅎㅎ 바로 Skip 이라는 결과 값이 출력이 됩니다. 하지만 조금 이상하지 않나요? 보통 프로그래밍 범위는 { } 안에서만 유효해야할텐데 'Ralf' 가 아닌 'Skip' 이 출력이 되는것이 이해하기가 좀 어렵습니다. 그럼 좀 더 난이도를 올려보겠습니다.!!
아래와 같은 요구사항이 있다고 가정을 해보고 코드를 구현을 해보겠습니다.
- 재고가 없으면 0을 반환합니다
- 어떤 상품이 할인 중이고 재고가 있다면 할인 가격을 반환합니다
- 어떤 상품이 할인중이 아니거나 할인중이라도 할인 상품의 재고가 없다면 정상 가격을 반환합니다.
function getLowesPrice(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;
}
위에 작성한 요구사항을 만족하는 함수를 작성해 보았습니다. 그럼 테스트를 해볼까요 ?
inventory 현재 재고수
price 현재 가격
salePrice할인 가격
saleInventory 할인 가능한 재고수
어떤 상품이 할인중이 아니고 재고도 없는경우 0을 반환
const item = {
inventory: 0,
price: 3,
salePrice: 0,
saleInventory: 0,
};
위에 있는 테스트 케이스는 어떤 상품도 할인중이 아니고 현재 재고도 없는경우입니다. 기대 값은 0이 나와야 하고 코드를 실행하면 0이 출력이 되는것 확인을 할수 있습니다.
그럼 다음 테스트는 어떻까요 ?
할인중이고 할인 상품의 재고가 있는경우 할인 가격을 반환
const item = {
inventory: 3,
price: 3,
salePrice: 2,
saleInventory: 1,
};
할인중이고 할인 상품의 재고가 있는경우 할인된 가격을 반환을 해야합니다. 코드를 실행을 했을때는 기대값은 2이고 결과값 역시 2입니다.
위 두개의 테스트를 통과하였습니다. 그럼 아래 테스트는 어떻까요 ?
할인중이지만 할인 상품 재고가 없는경우에는 정상 가격을 반환
const item = {
inventory: 3,
price: 3,
salePrice: 2,
saleInventory: 0,
};
할인중이지만 할인 상품 재고가 없는경우에는 정상가격을 반환을 해야합니다. 코드를 실행을 해보면 기대값 3이 아닌 0이 출력이 된다는것을 알수 있습니다. 해당 함수에 어디가 문제가 있은걸까요 ?
문제는 count 라는 같은 이름의 변수를 재할당한것이 문제였습니다 !! var 를 사용할 경우에는 동일한 변수 명을 사용할경우 block-scope 가 어디든 재할당된 값이 유효한것입니다.
함수와 같이 var 를 사용해 보겠습니다.
var test = 'print var variable'
function printVar() {
console.log(test)
}
function varCall() {
var test = 'call var variable'
printVar()
}
varCall()
아까의 조건문 처럼 var 로 선언된 test가 'call var variable' 로 호출할것으로 보입니다. 하지만 출력은 'print var variable' 로 출력이 됩니다. 그 이유는 var 에서는 lexical scope 를 따르고 있기 때문입니다. lexical scope는 어휘적 유효범위라고 하는데 풀어서 설명을 하면 함수를 어디서 선언 하였는지에 따라 상위 스코프를 결정을 합니다. 즉 호출하였을때의 스코프가 아닌 선언을 한 상위 스코프가 결정을 하는것입니다. 여기서 printVar의 함수 상위 스코프는 전역 스코프가 되고 그럼 var test = 'print var variable' 을 가리키게 됩니다.
유효범위가 어휘적으로 된다면 위험해 보입니다. 왜냐하면 큰 단위에 프로젝트를 할때 여러명이 협업을 한다고 하면 변수명이 섞일 위험도 있고 라이브러리를 사용한다고 했을때도 변수명이 재할당이 되어 제대로 동작을 안할수가 있기 때문입니다.
블록 유효 범위 (Block-Scope)
ES6 에서는 블록 스코프를 따르는 let과 const 를 사용할수가 있습니다. 아까의 테스트에서 통과가 안되었던 함수를 let 으로 변환해서 실행해 보겠습니다.
function getLowesPrice(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;
}
// 통과 못한 테스트
const item = {
inventory: 3,
price: 3,
salePrice: 2,
saleInventory: 0,
};
결과 값으로 3이 통과가 되는것을 확인을 하실수 있을까요 ? 블록 스코프 단위로 변수를 격리를 하니 변수명이 동일해도 블록스코프 내에만 유효하기때문에 해당 테스트가 통과하는것입니다. 그래도 왠만해서는 하나의 함수내에 변수명을 동일하는것은 가독성 측면에도 좋지 않아 피해야할것 갔습니다.
ES6 이후에서는 변수를 할당할때 const 와 let 을 사용을 합니다. const 와 let 의 차이는 값의 변동 가능 여부입니다.
간단하게 테스트를 해보겠습니다.
const testCon = 'test1234';
testCon = 'test111';
const 로 재할당한 위 코드를 실행하면 아래와 같은 에러가 출력이 됩니다.
const 는 let 과 다르게 한번 선언된 값에 대해서 변화가 되지 않습니다. 하지만 이값이 숫자나 문자열이 아닌 객체라면 이야가기 달라집니다. const 는 블록 문맥 내에서 재할당 할수 없는 변수 선언 방식입니다. 한번 선언이 된다면 이후 값을 변경을 할수가 없습니다. 하지만 const 는 값을 변경을 하는거지 불변값이 되는건 아닙니다.
아래 코드를 실행해 보겠습니다.
const testObj = {
a: 'test',
b: 123,
};
testObj.a = 123;
testObj.b = 'test123';
console.log(testObj);
const 라고 해서 모든 값을 수정을 없는게 아닌 객체는 수정을 할수 있다는것을 확인할수가 있었습니다.
지금까지 var의 어휘적 유효 범위와 ES6의 const,let을 살펴보았습니다. 여기까지 긴글 읽어 주셔서 감사합니다.
'개발이야기 > Javascript' 카테고리의 다른 글
화살표 함수(Arrow Function) (0) | 2021.03.20 |
---|---|
IIFE(즉시실행 함수) (0) | 2021.03.17 |