티스토리 뷰
아니, 변수 할당에 대해서 이렇게 깊게 공부할 필요가 있나 싶지만 나는 재미가 있다. 알고 싶었던 것을 알게 되니깐...
ES5(ECMAScript2015)에서는 var 키워드로만 변수를 선언했다면, ES6(ECMAScript2016)에서는 추가적으로 let, const 키워드도 변수를 선언할 수 있다.
왜? 기존의 var 키워드에서 const, let 키워드가 추가되었을까?
왜냐하면 var 키워드로 변수를 선언할 때 많은 이슈들이 발생하기 때문이다.
즉, var의 단점을 보완하기 위해서 새로운 키워드를 추가했다.
먼저, var 특징을 알아보자.
var 키워드로 변수를 선언할 때, 전역 스코프 또는 함수(지역) 스코프가 될 수 있다.
함수 외부에서 var키워드로 변수를 선언을 했다면, 해당 변수는 전역 변수이다. 그리고 전역 스코프를 가진다.
함수 내부에서 var 키워드로 변수를 선언했다면, 해당 변수는 지역 변수이다. 그리고 함수(지역) 스코프를 가진다. 또 함수 스코프는 함수 내부에 선언된 변수는 함수 내부에서만 접근(참조) 가능하다. 함수 외부에서 함수 내부의 변수를 접근한다면, 오류가 발생한다.
var string = 'hello' ; // 전역 변수
function printNumber(){
var number = 1; // 지역 변수
}
console.log(number); // Uncaught ReferenceError: number is not defined
변수의 재할당이 가능하다. 더불어 같은 재할당할 변수명이 같아도 어떠한 에러가 발생하지 않는다.
var name = 'KangHanNa';
var name = 'KimHanNa';
console.log(name); // KimHanNa
위의 코드를 아래와 같이 표현 가능하다.
var name = 'KangHanNa';
name = 'KimHanNa';
console.log(name); // KimHanNa
var 키워드로 선언한 변수는 호이스팅이 된다. 즉, 코드가 실행되기 전에 해당 스코프의 최상단으로 이동된다.
console.log(number); // undefined
var number = 1;
위의 코드는 자바스크립트가 아래와 같이 해석한다.
var number;
console.log(number); //undefined
number = 1;
그렇다면, 키워드 var로 인해 생기는 이슈들은 무엇일까?
같은 이름 가진 변수에 재할당을 해도 어떠한 에러가 생기지 않는다. 물론, 변수의 재할당을 염두에 두고 코드를 작성했다면 큰 문제가 되지 않는다. 혹시나 재할당 전에 선언한 변수를 인지하지 못할 경우는 큰 문제가 될 수 있다.
var number = 0;
// 100줄 이상의 코드가 있다고 가정
var number = 1; // 나 또한 다른 개발자가 5행의 재할당한 값을 인지하지 못했다. 그리고 출력값으로 0을 예상했다.
// 100줄 이상의 코드가 있다고 가정
console.log(number); // 1
위와 같이 간단하게 화면에 출력하는 용도로 변수를 이용해서 크게 와닿지 않겠지만, 예상할 수 없는 결과값이 출력된다고 생각한다면 디버깅하는데 시간이 많이 걸릴 수 있다고 생각한다.
그래서 ES6에서 let, const 키워드가 필요하다.
let 키워드는 블록 스코프이다. 블록 스코프는 중괄호({})안에서 스코프가 정해져있다. 그래서 중괄호 안에 선언된 변수는 블록 스코프를 따른다. 그래서 아래의 코드를 보면, 함수 printNumber 외부에서 let 키워드로 함수 printNumber 내부에 선언된 변수 number에 접근하면 에러가 발생한다. 왜냐하면 let 키워드로 선언한 변수는 블록 스코프이기 때문이다.
let string = 'Hello';
function printNumber() {
let number = 1;
console.log(number); // 1
}
printNumber(); // 1
console.log(number); // Uncaught ReferenceError: number is not defined
let은 재할당이 가능하다.
let number = 0;
number = 1;
console.log(number); // 1
재선언은 불가능하다. 즉, 같은 변수명에 할당하면 에러가 발생한다.
let number = 0;
let number = 1; // Uncaught SyntaxError: Indentifier 'number' has already been declared
//
let도 호이스팅 된다. 다만, var 키워드와 달리 let 키워드는 선언과 초기화가 동시에 되지 않는다. 그래서 let 키워드로 변수를 선언하기 전에 변수에 접근한다면 Refference Error가 발생한다.
function printNumber(){
console.log(number);
let number = 0;
}
printNumber(); // Uncaught ReferenceError: Cannot access 'number' before initialization
마지막으로 const 키워드를 알아보자.
const 키워드도 블록 스코프이다. 그래서 let 키워드와 유사한 점이 있다. 중괄호({})안에 선언된 변수는 접근 가능하다. 단, 한 번 선언하면 변경이 불가능하다. 그래서 보통 const 키워드를 가지고 변수를 선언했을 때, 값이 변경되지 않는다는 것을 추측할 수 있지만, 갑이 변경되는 경우도 있다. 할당할 값이 배열, 객체 등 mutable 한 데이터의 경우 변경이 값이 변경됩니다.
재할당이 불가능하다.
const number = 0;
number = 1; // Uncaught TypeError: Assignment to constant variable.
재선언이 불가능하다.
const number = 0;
const number = 1; // Uncaught SyntaxError: Identifier 'number' has already been declared
var 사용하기 보다 let, const 키워드 사용할 것을 추천한다. const 사용이 더 좋다고 한다. 왜냐하면 재할당을 피할 수 있고, 값을 변경하지 않을 것이라는 상대방에게 의도를 전달할 수 있기 때문이다.