[JavaScript] 15장. let, const 키워드와 블록 레벨 스코프

west·2024년 8월 14일
post-thumbnail

15.1 var 키워드로 선언한 변수의 문제점

15.1.1 변수 중복 선언 허용

  • var 키워드로 선언한 변수는 중복 선언이 가능
var x = 1;
var y = 2;

// var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용함 
// 초기화문이 있는 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작함 
var x = 100;
var y; 

console.log(x); // 100 
console.log(y); // 1 
  • 초기화문이 있는 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작
  • 초기화문이 없는 변수 선언문은 무시됨 (에러 발생 x)

15.1.2 함수 레벨 스코프

  • var 키워드로 선언한 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정함
  • 함수 외부에서 var 키워드로 선언한 변수는 코드 블록 내에서 선언해도 모두 지역 변수가 됨
  • 함수 레벨 스코프는 전역 변수를 남발할 가능성을 높여 전역 변수가 중복 선언되는 경우가 발생함
var x = 1;
if(true) {
	var x = 10;
}
console.log(x); // 10 
var i = 10; 
// for문에서 선언한 i는 전역 변수임 
for(var i = 0; i < 5; i++) {
	console.log(i); // 0 1 2 3 4 
} 
console.log(i); // 5 

15.1.3 변수 호이스팅

  • var 키워드로 변수를 선언하면 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작함
// 이 시점에는 변수 호이스팅에 의해 이미 foo 변수가 선언됨
// 변수 foo는 undefined로 초기화됨 
console.log(foo);

// 변수에 값 할당
foo = 123;

console.log(foo); // 123
// 변수 선언은 런타임 이전 암묵적 실행 
var x;

15.2 let 키워드

15.2.1 중복 선언 금지

  • let 키워드로 이름이 같은 변수를 중복 선언하면 문법 에러(SyntaxError)가 발생함
var foo = 123; 
// var 키워드로 선언한 변수는 같은 스코프 내 중복 선언 허용 
var foo = 456; 

let bar = 124; 
let bar = 23; // SyntaxError

15.2.2 블록 레벨 스코프

  • let 키워드로 선언한 변수는 모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등)을 지역 스코프로 인정하는 블록 레벨 스코프(block-level scope)를 따름
let foo = 123; // 전역 변수 

{
	let foo = 2; // 지역 변수 
	let bar = 3; // 지역 변수 
}
console.log(foo); // 123
console.log(bar); //ReferenceError

15.2.3 변수 호이스팅

  • let 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 동작함
console.log(foo); // ReferenceError
let foo; 
  • var 키워드로 선언한 변수는 선언 단계와 초기화 단계가 한번에 진행됨
  • let 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행
    • 런타임 이전에 암묵적으로 선언 단계가 먼저 실행되지만 초기화 단계는 변수 선언문에 도달했을 때 실행됨

    • 만약 초기화 단계가 실행되기 이전에 변수에 접근하려고 하면 참조 에러 발생

    • 일시적 사각지대: 스코프 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간

      // 런타임 이전에 선언 단계 실행 
      console.log(foo); // ReferenceError
      
      let foo; // 변수 선언문에서 초기화 단계 실행 
      console.log(foo); // undefined 
      
      foo = 1;
      console.log(foo); // 1 

15.2.4 전역 객체와 let

  • let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아님
    • window.foo와 같이 접근할 수 없음
let x = 1; 
console.log(window.x); // undefined
console.log(x); // 1

15.3 const 키워드

  • const 키워드는 상수를 선언하기 위해 사용함

15.3.1 선언과 초기화

const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화를 해야 함

const foo; // SyntaxError
  • const 키워드로 선언한 변수는 let 키워드로 선언한 변수와 마찬가지로 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생하지 않는 것처럼 동작함
{
	console.log(foo); // ReferenceError
	const foo = 1;
	console.log(foo); // 1
}
	// 블록 레벨 스코프를 가짐 
	console.log(foo); // ReferenceError

15.3.2 재할당 금지

  • const 키워드로 선언한 변수는 재할당이 금지됨
const foo = 1;
foo = 2; // TypeError

15.3.3 상수

  • const 키워드로 선언한 변수에 원시 값을 할당한 경우 변수 값을 변경할 수 없음
  • 상수는 재할당이 금지된 변수를 뜻함
  • const 키워드로 선언된 변수에 원시 값을 할당한 경우 원시 값은 변경할 수 없는 값이고 const 키워드에 의해 재할당이 금지되므로 할당된 값을 변경할 수 있는 방법은 없음
    • 상수 이름은 대문자로 선언해 상수임을 명확히 나타냄
    • 여러 단어로 이뤄진 경우는 언더스코어로 구분해 스네이크 케이스로 구분하는 것이 일반적
const TAX_RATE = 0.1;

let preTaxPrice = 100;
let afterTaxPrice = preTaxPrice + (preTaxPrice * TAX_RATE); 

console.log(afterTaxPrice); 

15.3.4 const 키워드와 객체

  • const 키워드로 선언된 변수에 객체를 할당한 경우 값을 변경할 수 있음
    • 변경 불가능한 값인 원시 값은 재할당 없이 교체할 수 있는 방법이 없음
    • 변경 가능한 값인 객체는 재할당 없이도 직접 변경이 가능함
const person = {
	name: 'Lee'
}
// 객체는 변경 가능한 값이므로 재할당 없이 변경 가능함
person.name = 'Kim';

console.log(person); // {name: 'Kim'} 
  • const 키워드는 재할당을 금지할 뿐 “불변”을 의미하지는 않음
    • 새로운 값을 재할당하는 것은 불가능하지만 프로퍼티 동적 생성, 삭제, 프로퍼티 값의 변경을 통해 객체를 변경하는 것은 가능함
    • 객체가 변경되더라도 변수에 할당된 참조 값은 변경되지 않음

15.4 var vs. let vs. const

  • 변수 선언에는 기본적으로 const 를 사용하고 let 은 재할당이 필요한 경우에 한정해 사용하는 것이 좋음
  • var, let, const 키워드는 다음과 같이 사용하는 것을 권장함
    • ES6를 사용한다면 var 키워드는 사용되지 않음
    • 재할당이 필요한 경우 한정해 let 키워드 사용 (변수 스코프 최대한 좁게)
    • 변경이 발생하지 않고 읽기 전용으로 사용하는 원시 값과 객체에는 const 키워드 사용
      • const 키워드는 재할당을 금지하므로 var, let 보다 안전함
profile
산타 fe

0개의 댓글