var
키워드로 선언한 변수는 중복 선언 가능var x = 1;
var y = 1;
var x = 100;
var y;
console.log(x); // 100
console.log(y); // 1
var
키워드로 선언한 변수는 함수 레벨 스코프를 따름var x = 1;
if (true) {
var x = 10;
}
console.log(x); // 10
var i = 10;
for (var i = 0; i < 5; i++) {
console.log(i); // 0 1 2 3 4
}
console.log(i); // 5
var
키워드로 선언한 변수는 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어올려진 것처럼 동작console.log(foo); // undefined
foo = 123;
console.log(foo); // 123
var foo;
var
키워드의 단점을 보완하기 위해 let
, const
도입
let
키워드로 선언한 변수는 중복 선언하면 문법 에러 발생var foo = 123;
var foo = 456;
let bar = 123;
let bar = 456; // SyntaxError: Identifier 'bar' has already been declared
let
키워드로 선언한 변수는 모든 코드 블록을 지역 스코프로 인정하는 블록 레벨 스코프를 따름let foo = 1;
{
let foo = 2;
let bar = 3;
}
console.log(foo); // 1
console.log(bar); // ReferenceError: bar is not defined
let
키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 동작함
let
키워드로 선언한 변수는 '선언 단계'와 '초기화 단계'가 분리되어 진행
// 런타임 이전 선언 단계
console.log(foo); // ReferenceError: foo is not defined
let foo; // 변수 선언문 : 초기화 단계
console.log(foo); // undefined
foo = 1; // 할당 단계
console.log(foo); // 1
let
키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 보이지만, 사실 그렇지 않음let foo = 1;
{
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
let foo = 2;
}
→ 변수 호이스팅이 발생하지 않는다면, 위의 예제에서 전역 변수 foo
값을 출력
→ 하지만, let
키워드로 선언한 변수도 호이스팅이 발생하기 때문에 참조 에러(ReferenceError) 발생
var
키워드로 선언한 전역 변수와 전역 함수, 선언하지 않은 변수에 값을 할당한 암묵적 전역은 전역 객체 window
의 프로퍼티가 됨
전역 객체의 프로퍼티를 참조할 때 window
를 생략할 수 있음
var x = 1;
y = 2;
function foo() {}
console.log(window.x); // 1
console.log(x); // 1
console.log(window.y); // 2
console.log(y); // 2
console.log(window.foo); // f foo() {}
console.log(foo); // f foo() {}
let x = 1;
console.log(window.x); // undefined
console.log(x); // 1
const
키워드는 상수를 선언하기 위해 사용
const
키워드의 특징은 let
키워드와 대부분 동일
const
키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 함const foo; // SyntaxError: Missing initalizer in const declaration
let
키워드와 동일하게 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생하지 않는 것처럼 동작{
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
const foo = 1;
console.log(foo); // 1
}
console.log(foo); // ReferenceError: foo is not defined
const
키워드로 선언한 변수는 재할당이 금지됨const foo = 1;
foo = 2; // TypeError: Assignment to constant variable
상수는 재할당이 금지된 변수
const
키워드로 선언한 변수에 원시 값을 할당한 경우 변수 값을 변경할 수 없음
const TAX_RATE = 0.1;
let preTaxPrice = 100;
let afterTaxPrice = preTaxPrice + (preTaxPrice * TAX_RATE)
const
키워드로 선언한 변수에 원시 값을 할당한 경우 변수 값을 변경할 수 없음
하지만, const
키워드로 선언한 변수에 객체를 할당한 경우 변수 값을 변경할 수 있음
→ const
키워드는 재할당을 금지할 뿐 "불변"을 의미 X
이때 객체가 변경되더라도 변수에 할당된 참조 값은 변경되지 않음
const person = {
name: 'Lee'
};
person.name = 'Kim';
console.log(person); // {name: "Kim"}
변수 선언에 기본적으로 const
를 사용하고,
let
은 재할당이 필요한 경우 한정해 사용하는 것이 좋음
사용 권장
var
: 사용을 권장하지 않음let
: 재할당이 필요한 경우에 한정, 변수의 스코프는 최대한 좁게const
: 변경이 발생하지 않고 읽기 전용으로 사용하는 원시 값과 객체var
, let
키워드보다 안전