
변수(variable)는 하나의 값을 저장하기 위해 확보된 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름으로 변수에 값을 저장하는 것을 할당(assignment)이라고 하고 저장한 값을 읽는 것을 참조(reference)라고 한다.
변수를 사용하기 위해선 선언을 해야하는데 이때 사용하는 것이 바로 var, const, let 이다.
ES5까지는 변수 선언을 위해선 오직 var만 사용할 수 있었다. 하지만 ES6에서 const 와 let이 var의 단점을 보완하기 위해 도입되었다.
var : 함수레벨 스코프(function-level scope), 재할당 O, 중복선언 O
const : 블럭레벨 스코프(block-level scope), 재할당 X, 중복선언 X
let : 블럭레벨 스코프(block-level scope), 재할당 O, 중복선언 X
스코프는 '유효범위'를 뜻하는데 선언한 변수를 참조할 수 있는 범위를 나타낸다. 스코프는 2가지로 구분 할 수 있는데 말 그대로 어디에서든지 참조가 가능한 전역 스코프 (Global scope)와 자신이 속한 지역에서만 참조가 가능한 지역 스코프 (Local scope)가 있다.
그렇다면 var의 함수레벨 스코프와 const와 let의 블럭레벨 스코프는 무엇을 의미할까?
함수레벨 스코프는 변수가 함수 내에서 선언되었을 경우엔 해당 함수 내에서만 참조가 가능한 지역 스코프가 되지만 함수가 아닌 곳에서 선언되었을 경우 모든 곳에서 참조가 가능한 전역 스코프가 되는 것을 말한다.
예를 들면 다음과 같다.
var name = "dohun";
function count() {
var age = "26";
console.log(name); //dohun
console.log(age); //26
}
count();
if(name === "dohun") {
var a = 1;
var b = 2;
console.log(a + b) //3
}
console.log(name); //dohun
console.log(a); //1
console.log(b); //2
console.log(age); //Uncaught ReferenceError: age is not defined
var를 사용하여 함수 밖에서 선언된 name, a, b 전역변수로 모든 곳에서 참조가 가능했지만 함수 내에서 선언된 age는 함수에서는 참조가 가능하고 밖에서는 참조오류가 발생하였다.
var를 이제 사용하지 않는 이유는 사용시 전역변수가 많아지기 때문에 변수 이름이 중복되고 의도치 않은 재할당으로 코드를 예측하기 어렵게 만들기 때문이다.
블록레벨 스코프는 변수가 함수뿐만 아니라 다른 블록에서 선언되었을 때에도 지역 스코프가 되는 것을 의미한다.
const name = "dohun";
function count() {
const age = "26";
console.log(name); //dohun
console.log(age); //26
}
count();
if(name === "dohun") {
const a = 1;
const b = 2;
console.log(a + b) //3
}
console.log(name); //dohun
console.log(a); //Uncaught ReferenceError: a is not defined
console.log(b); //Uncaught ReferenceError: b is not defined
console.log(age); //Uncaught ReferenceError: age is not defined
이렇게 const를 사용하게 되면(같은 블록레벨 스코프인 let을 사용해도 결과는 같다.) 블록 밖에 있는 name만이 전역변수로 설정되어 밖에서 참조가 가능하고 블록 안에 있는 a, b, age는 참조오류가 발생하게 된다.
재할당이란 선언한 변수의 값을 나중에 변경을 하는 것을 말하는데 var, let은 재할당이 가능한 키워드이다.
let name = "dohun";
console.log(name) //dohun
name = "doooooohunnnnn"
console.log(name) //doooooohunnnnn
하지만 const로 선언하게 되면
const name = "dohun";
console.log(name) //dohun
name = "doooooohunnnnn"
console.log(name) //Uncaught TypeError: Assignment to constant variable.
Uncaught TypeError: Assignment to constant variable. 이렇게 타입오류가 발생하게된다. 왜냐하면 const는 재할당이 불가능한 상수의 개념이기 때문이다.
중복선언이란 말 그대로 같은 이름의 변수를 중복으로 선언하는 것을 말한다.
var는 가능하고 const, let은 불가능한데
var name = "dohun"
console.log(name) //dohun
var name = "doooooohunnnnn"
console.log(name) //doooooohunnnnn
var를 사용하면 이렇게 값이 나오지만
let name = "dohun"
console.log(name)
let name = "doooooohunnnnn"
console.log(name)
let을 사용하면 Uncaught SyntaxError: Identifier 'name' has already been declared와 같이 문법오류가 발생하게 된다.