ES6(ECMA Script 2015, 줄여서 ES6)로 넘어오면서 기존 ES5 까지 사용하던 변수 선언 키워드인 var에다 const와 let이라는 키워드가 추가되었습니다. 물론 var 없이도 변수를 선언할 수 있습니다만, 그렇게 되면 전역객체(브라우저 환경에서는 window 객체)의 속성이 되기 때문에 동일한 이름의 변수를 사용하다가는 치명적인 문제가 발생할 수도 있습니다.
기존 자바스크립트의 변수는 기본적으로 Function Scope 입니다(var 로 선언한 변수). 변수의 유효범위가 함수단위라는 이야기입니다. java 나 C 등의 많이 사용되는 프로그래밍 언어를 공부해 보았다면 알겠지만, 대체로 이 언어들은 Function Scope 가 아닌 Block Scope 를 가집니다.(python 은 예외) 그래서 java 나 C 계열의 언어를 사용하다가 자바스크립트 코드를 짜다보면 간혹 스코프 문제로 헷갈릴때가 있기 마련이죠. 그래서 ES6 부터는 const 와 let 이 등장했습니다. 예상한대로 const 와 let 은 Block Scope 를 가집니다. 기존에 많이 사용되는 언어들과 같습니다. const 는 단어의 의미처럼 상수를 의미하고 let은 기존의 var 처럼 변수를 의미합니다.
이 밖에도 이 세가지 키워드에는 몇가지 차이점이 존재합니다. 예제를 통해 이 세가지 변수선언 키워드에 대해서 알아보겠습니다.
재할당 및 재선언하기
// var의 경우
var a = 1
a = 2
console.log(a) // 2
var a = 3
console.log(a) // 3
// let의 경우
let b = 1
b = 2
console.log(b) // 2
let b = 3 // SyntaxError: Identifier 'b' has already been declared
// const의 경우
const c = 1
c = 2 // TypeError: Assignment to constant variable
var 의 경우 굉장히 유연합니다. var a = 1;로 선언한 뒤, 2 를 재할당하고 다시 var = 3;으로 재선언(?) 해도 문제될게 없습니다. 그런데 let 의 경우 재할당은 문제 없습니다만, let b = 3;으로 재선언하고 나면 이미 선언된 변수라는 에러를 뱉어냅니다. 마지막으로 const 는 상수이기 때문에 재할당, 재선언 모두 불가합니다.
스코프 (Scope)
var a = 1
let b = 2
if (true) {
var a = 11
let b = 22
console.log('a = ' + a) // 11
console.log('b = ' + b) // 22
}
console.log('a = ' + a) // 11
console.log('b = ' + b) // 2
function func() {
var a = 111
let b = 222
console.log('a = ' + a) // 111
console.log('b = ' + b) // 222
}
func()
console.log('a = ' + a) // 11
console.log('b = ' + b) // 2
전역 영역에서 var a, let b 를 선언하고 각각 1, 2 를 할당했습니다.
우선 if 블럭 내에서 각각의 변수 값을 변형시켰더니 블럭 내에서는 변경된 값이 모두 출력되었습니다.
그런데, if 블럭 바깥으로 나갔더니 let 으로 선언했던 b 값은 가장 상단에 선언한 값과 동일한 2 인데, a 는 11 로 변경되었습니다. 그 이유는 var 의 경우 변수의 유효범위가 함수이므로 블럭으로 감쌌다고 하더라도 함수 스코프가 바뀐것이 아니기 때문에 if 블럭 내에서 재할당한 값을 출력하는 것입니다.
함수내에서 a, b 각 변수를 선언했을때는 어떨까요? var 든, const 든 새로운 함수로 감싸게 되면 그 안에서 선언한 변수는 함수(func)내의 지역변수가 되므로 바깥에서 선언한 변수의 이름과 겹치더라도 함수(func) 내에서는 새로 할당한 값들이 출력됩니다. 마지막으로 함수가 호출되고 나서 각 변수를 출력해보면, 함수 내에서 할당한 값은 그 함수 호출이 끝남과 동시에 유효범위도 사라지므로 함수 선언 이전의 a, b 값이 출력됩니다.
let vs const
위에서 let 은 변수, const 는 상수라고 구분지어 설명했지만, 좀더 구체적으로 설명할 필요가 있어보입니다.
let 은 변수고 const 는 상수가 맞긴 하지만, 할당된 값이 원시타입이냐 참조타입(array, object, function)이냐에 따라서 조금 다르게 사용됩니다.
let a = 1
const b = 2
a = 11
b = 22 // TypeError: Assignment to constant variable.
let obj_a = {
name: 'obj_a',
}
const obj_b = {
name: 'obj_b',
}
obj_a['name'] = 'a'
obj_b['name'] = 'b'
obj_a['number'] = 1
obj_b['number'] = 2
obj_a = {}
obj_b = {} // TypeError: Assignment to constant variable.
기본적으로 let 은 재할당이 가능한반면, const 는 재할당이 불가합니다.
재할당하게 되면 TypeError 가 발생하죠. 그런데 차이점이 있다면, 처음 할당된 객체를 변형시킬때는 아무 문제없이 동작한다는 것을 알 수 있습니다. 처음에는 두 객체 모두 ‘name’ 이라는 속성만 가지고 있었는데, 이를 변형하거나 새로운 속성(number)를 추가하더라도 let, const 둘다 에러를 발생시키지 않습니다.
이는 array 와 function 의 경우도 마찬가지인데, 이유는 const 에 실제로 할당된 값은 원시타입처럼 특정 값이 아니라 객체의 주소값이기 때문입니다. 실제 객체가 변한다고해서 한번 할당된 객체의 주소값이 바뀌는건 아니죠.
결론
ES6 에서 var, const, let 모두 사용 가능하지만, 상황에 맞게 적절한 키워드를 사용해야 하겠습니다.
(되도록 const, let 을 사용하는게 좋겠죠)
객체를 새로 할당할 특별한 이유(이런 경우는 드물다 생각합니다)가 없다면 되도록 const 를 사용하여 객체를 선언하는게 좋을것 같습니다.
https://blueshw.github.io/2017/03/28/ES-var-VS-const-VS-let/
'javascript' 카테고리의 다른 글
로또 추첨 만들기 (0) | 2019.09.26 |
---|---|
javascript 끝말잇기 (0) | 2019.09.26 |
삼항 조건 연산자 (0) | 2019.09.25 |
이벤트 중단 방법 (0) | 2019.09.25 |
반복문으로 구구단 (0) | 2019.09.25 |