Modern JavaScript Deep Dive 스터디 - CH15 let, const 키워드와 블록 레벨 스코프
참고 자료: ⟪모던 자바스크립트 Deep Dive⟫"(이웅모 지음,위키북스, 2020)
var x = 1;
var y = 1;
// var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용
// 초기화문이 있는 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작
var x = 100;
// 초기화문이 없는 변수 선언문은 무시
var y;
console.log(x); // 100
console.log(y); // 1
var i = 10;
// for문의 i도 전역 변수 -> 이미 선언된 전역 변수 i가 있으므로 중복 선언.
for (var i = 0; i < 5; i++) {
console.log(i); // 0 1 2 3 4
}
// 의도치 않게 i 변수의 값이 변경
console.log(i); // 5
가독성을 떨어뜨리고 오류를 발생시킬 가능성 ↑
호이스팅
- 변수 선언이 스코프의 시작 부분으로 끌어 올려진 것처럼 동작
- 스코프 단위로 동작
- 선언문 이전에 참조하는 경우 undefined를 반환
- 전역 변수 호이스팅: 전역 변수의 선언이 전역 스코프 선두로 끌어 올려진 것처럼 동작 -> 전역 전체에서 변수 유효
- 지역 변수 호이스팅: 지역 변수 선언이 지역 스코프 선두로 끌어 올려진 것처럼 동작 -> 함수 전체에서 변수 유효
var 키워드 단점을 보완하기 위해 ES6에서는 새로운 변수 선언 키워드인 let과 const를 도입
let bar = 123;
// 같은 스코프 내에서 중복 선언을 허용하지 않음
let bar = 456; // SyntaxError: Identifier 'bar' has already been declared
let foo = 1; // 전역 변수
{
let foo = 2; // 지역 변수
let bar = 3; // 지역 변수
}
console.log(foo); // 1
console.log(bar); // ReferenceError: bar is not defined
let foo = 1; // 전역 변수
{
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
let foo = 2; // 지역 변수
}
ReferenceError
발생// 런타임 이전에 선언 단계가 실행. 아직 변수가 초기화되지 않음.
// 초기화 이전의 일시적 사각 지대에서는 변수를 참조할 수 없음.
console.log(foo); // ReferenceError: foo is not defined
let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined
foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
전역 객체
- var 키워드로 선언한 전역 변수 -> 전역 객체
window
의 프로퍼티- 전역 객체는 브라우저 환경 내에서 참조 가능
- 전역 객체의 프로퍼티를 참조할 때 window를 생략 가능
- let 키워드 로 선언한 전역 변수는 전역 객체의 프로퍼티가 아님 -> window 객체에 접근 불가
- let 전역 변수는 DER에 존재하기 때문
- DER: 전역 렉시컬 환경의 선언적 환경 레코드. 보이지 않는 개념적인 블록
// 이 예제는 브라우저 환경에서 실행해야 한다.
// 전역 변수
var x = 1;
// 암묵적 전역
y = 2;
// var 키워드로 선언한 전역 변수는 전역 객체 window의 프로퍼티다.
console.log(window.x); // 1
// 전역 객체 window의 프로퍼티는 전역 변수처럼 사용할 수 있다.
console.log(x); // 1
console.log(window.y); // 2
console.log(y); // 2
// 이 예제는 브라우저 환경에서 실행해야 한다.
let x = 1;
// let, const 키워드로 선언한 전역 변수는 전역 객체 window의 프로퍼티가 아니다.
console.log(window.x); // undefined
console.log(x); // 1
SyntaxError
발생const foo; // SyntaxError: Missing initializer in const declaration
const foo = 1;
foo = 2; // TypeError: Assignment to constant variable.
// 세율을 의미하는 0.1은 변경할 수 없는 상수로서 사용될 값이다.
// 변수 이름을 대문자로 선언해 상수임을 명확히 나타낸다.
const TAX_RATE = 0.1;
// 세전 가격
let preTaxPrice = 100;
// 세후 가격
let afterTaxPrice = preTaxPrice + (preTaxPrice * TAX_RATE);
console.log(afterTaxPrice); // 110
const person = {
name: 'Lee'
};
// 객체는 변경 가능한 값이다. 따라서 재할당없이 변경이 가능하다.
person.name = 'Kim';
console.log(person); // {name: "Kim"}
const
를 사용하고 let
은 재할당이 필요한 경우에 한정해 사용 권장var
키워드는 사용하지 않는게 안전함