변수 중복 선언 허용
var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언이 허용되는데, 이는 의도치 않게 변수값이 재할당되어 변경되는 부작용을 발생시킨다.
function foo() {
var num = 1;
var num = 10; // var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용한다.
console.log(num);
}
foo(); // 10
함수 레벨 스코프
대부분의 프로그래밍 언어는 모든 코드 블록(if, for, while, try/catch 등)이 지역 스코프를 만든다. 하지만 var 키워드로 선언된 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정한다.
case 1
// (var 키워드로 변수 선언)
var num = 1;
if (true) {
// var 키워드로 선언된 변수는 함수의 코드 블록만을 지역 스코프로 인정한다.
// 따라서 if 코드블럭에서 선언하였다 하더라도 전역 변수로 선언된다. 이미 선언된 전역 변수가 있으므로 변수는 중복 선언된다.
// 이는 의도치 않게 변수 값이 변경되는 부작용을 발생시킨다.
var num = 10;
}
console.log(num); // 10
case 2
// (var 키워드로 for문 안의 변수 선언)
var i = 10;
// for 문의 코드블럭에서 선언한 i는 전역 변수로 선언된다. 이미 선언된 전역 변수가 있으므로 마찬가지로 중복 선언된다.
for (var i = 0; i < 5; i++) {
console.log(i); // 0 1 2 3 4
}
// 의도치 않게 변수의 값이 변경되었다.
console.log(i); // 5
console.log(name) // undefined
var name = ‘choi’
위의 코드를 보면 변수를 선언하기전에 해당 변수를 콘솔에 찍어봐도 에러가 나지 않고 undefined가 출력된다. 왜냐하면 var 변수는 선언과 동시에 undefined로 초기화 되기 때문이다. 실행시점에 호이스팅에 의해 맨위로 끌려올려졌을때 해당 변수는 undefined 값을 가지고 있다.
이를 풀어서 보면
var name; // 실행시점에 name 변수가 호이스팅 되어 해당 위치로 이동하며, undefined 값을 가지고 있다.
console.log(name) // undefined
name = ‘choi’
let, const 공통 특징
- let과 const도 호이스팅이 된다. 다만, var는 선언과 초기화가 동시에 이뤄지지만, let, const는 호이스팅 되어 선언단계가 이뤄지고 초기화 단계는 실제 let, const가 사용된 코드에 도착했을 때 이뤄진다. 그렇기 때문에 초기화 단계 이전에 변수에 접근하려하면 reference 에러가 발생한다.
- let과 const 로 선언된 변수는 블록 레벨 스코프를 가진다.
모든 코드 블록(함수,if문,for문,while문,try/catch문 등)내에서 선언된 변수는 코드 블록 내에서만 유효하다.
재선언 불가능
let age = 29; let age = 33; // Identifier 'age' has already been declared 에러 console.log(age); 재할당 가능 let age = 29; age = 33; console.log(age); // 33
const 변수는 let과 매우 유사하지만 차이점은 const 로 선언되면 값이 상수화되어 변경이 불가능하다. 또한 const 로 선언할 경우 상수는 반드시 선언과 동시에 값을 할당하여 초기화 해줘야한다.
const age = 29; // 선언과 동시에 초기화 필요
const age; // Missing initializer in const declaration 에러
const age = 29;
age = 33; // Assignment to constant variable 에러