var
키워드로 선언한 변수는 중복으로 선언할 수 있기 때문에 초기화문의 유무에 따라서 다르게 동작함.
var x = 1;
var y = 1;
var x = 100; // 초기화문이 있는 변수 선언문은 var 키워드가 없는 것처럼 동작하여 값이 재할당됨.
var y; // 초기화문이 없는 변수 선언문은 무시됨.
console.log(x); // 100 출력
console.log(y); // 1 출력
만약 같은 이름의 변수가 이미 선언되어 있는 것을 모르고 변수를 중복으로 선언하고 값까지 할당했다면, 의도치 않게 이전에 선언된 변수의 값이 변경되는 부작용 발생!
var
키워드로 선언한 변수는 오직 '함수 레벨 스코프'만 지역 스코프로 인정하기 때문에 함수 외부에서 var
키워드로 선언한 변수는 코드 블록 안에 있어도 전역 변수가 됨.
함수 레벨 스코프는 의도치 않게 전역 변수가 중복 선언되는 경우가 발생할 수 있음.
var a = 1; // 전역 변수
if(true){
var a = 10; // 전역 변수 a 중복 선언
}
console.log(a); // 10 출력
// ----------------------------------
var i = 10; // 전역 변수
for(var i = 0; i < 5; i++){ // i
console.log(i); // 0 1 2 3 4 출력
}
console.log(i); // 5 출력
var
키워드로 변수를 선언하면 '변수 호이스팅'이 발생함.
변수 호이스팅에 의해 var
키워드로 선언한 변수는 변수 선언문 이전에 참조할 수 있음. ⇒ 가독성이 떨어지고 오류를 발생시킬 여지가 많아짐.
// 1) 변수 선언
// 2) 변수 초기화
console.log(name); // undefined 출력
name = 'Sol'; // 3) 변수 값 할당
console.log(name); // Sol 출력
var name; // 변수 호이스팅 발생
상기한 var
의 문제점을 보완하기 위해 ES6에서 새롭게 도입된 변수 선언 키워드
let
키워드로 선언한 변수를 중복 선언하면 SyntaxError 발생
var age1 = 20;
var age1 = 30; // 에러가 발생하지 않음.
// ------------------------
let age2 = 20;
let age2 = 30; // SyntaxError
let
키워드로 선언한 변수는 모든 코드 블록(if, for, while, try/catch, 함수)을 지역 스코프로 인정하는 '블록 레벨 스코프'를 가짐.
같은 이름을 가진 변수더라도 전역에서 선언된 변수와 코드 블록 내에서 선언된 변수는 별개의 변수로 인식됨!
let a = 1; // 전역 변수
{
let a = 2; // 지역 변수
let b = 3; // 지역 변수
}
console.log(a); // 1 출력
console.log(b); // ReferenceError
let
키워드로 선언한 변수는 '선언 단계'와 '초기화 단계'가 분리되어 진행됨. ⇒ 변수 호이스팅이 발생하지 않는 것처럼 동작함.
스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간인 '일시적 사각지대'가 존재함.
// 변수 선언
console.log(name); // ReferenceError
// -------------TDZ---------------
let name; // 변수 초기화
console.log(name); // undefined 출력
name = 'Sol'; // 변수 값 할당
console.log(name); // 'Sol' 출력
💡
let
키워드로 선언한 전역 변수는 암묵적 전역이 발생하지 않기 때문에 전역 객체의 프로퍼티가 아님.let
전역 변수는 전역 렉시컬 환경의 '선언적 환경 레코드(Declarative Environment Record)' 내에 존재하게 됨.
상수를 선언하기 위해 ES6에서 새롭게 도입된 변수 선언 키워드
let
키워드와 마찬가지로 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생하지 않는 것처럼 동작함.
const
키워드로 선언한 변수는 반드시 '선언'과 '초기화'를 동시에 해야 함.
const a = 1;
const b; // SyntaxError
const
키워드로 선언한 변수는 재할당이 금지됨.
const a = 1;
a = 2; // TypeError
const
키워드로 선언한 변수에 원시 값을 할당하면 그 값을 변경할 수 없음. ⇒ 재할당 금지
상수를 사용하면 유지 보수에 좋으며 가독성이 향상됨!
let preTaxPrice = 1000;
let afterTaxPrice = preTaxPrice + (preTaxPrice * 0.1); // 0.1의 의미를 정확히 알 수 없음.
console.log(afterTaxPrice); // 1100 출력
// -----------------------------------------------------
const TAX_RATE = 0.1; // 상수 사용
let preTaxPrice = 1000;
let afterTaxPrice = preTaxPrice + (preTaxPrice * TAX_RATE);
console.log(afterTaxPrice); // 1100 출력
💡
const
키워드로 선언된 변수에 원시 값이 아닌 객체를 할당한 경우, 그 값을 변경할 수 있음. 즉,const
키워드는 재할당을 금지하는 것이지 '불변'을 의미하는 것은 아님.
const person = {
name: 'Sol'
};
person.name = 'Ahn'; // 객체의 프로퍼티 변경 가능
console.log(person); // { name: 'Ahn' } 출력
const
키워드를 사용하고, 재할당이 필요한 경우에 한하여let
키워드를 사용할 것을 권장함![도서] 정재남, ⌜코어 자바스크립트⌟, 위키북스, 2019
[도서] 이웅모, ⌜모던 자바스크립트 Deep Dive⌟, 위키북스, 2020