모던 자바스크립트 Deep Dive - 15장 let, const 키워드와 블록 레벨 스코프

이혜란·2022년 11월 14일
0

JavaScript

목록 보기
13/33
post-thumbnail

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

✏️ 변수 중복 선언 허용

var 키워드로 선언한 변수는 중복 선언이 가능합니다. 따라서 의도치 않은 값의 변경이 발생할 수 있습니다.

var x = 1;
var y = 1;

// var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용한다.
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문에서 선언한 i는 전역 변수다.
for(var i = 0; i < 5; i++) {
  console.log(i); // 0 1 2 3 4
}

// 의도치 않게 i의 값이 변경되었다.
console.log(i); // 5

✏️ 변수 호이스팅

var 키워드로 변수를 선언하면 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작합니다.

// 이미 foo라는 변수가 선언되었다.
// 변수 선언문 이전에 참조가 가능하다.
console.log(foo); // undefined 초기화 단계

foo = 123; // 할당 단계

console.log(foo); // 123

var foo; // 변수 선언은 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 실행된다.

📚 let 키워드

var 키워드의 단점을 보완하기 위해 새로운 변수 키워드 let과 const가 도입되었습니다.

✏️ 변수 중복 선언 금지

let 키워드로 이름이 같은 변수를 중복 선언하면 문법 에러가 발생합니다.

let bar = 123;

let bar = 456; // SyntaxError 중복 선언을 허용하지 않는다.

✏️ 블록 레벨 스코프

let 키워드로 선언한 변수는 모든 코드 블록(함수, if문, for문, while문 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 따릅니다.

let foo = 1; // 전역 변수

{
  let foo = 2; // 지역 변수(전역 변수와 다른 별개의 변수)
  let bar = 3; // 지역 변수
}

console.log(foo); // 1
console.log(bar); // ReferenceError: bar is not defined

let i = 10; // 전역 스코프

function foo() {
  let i = 100;
  for(let i = 1; i < 3; i++) {
    console.log(i); // 1 2  블록 레벨 스코프
  }
  console.log(i); // 100 함수 레벨 스코프
}

foo();
console.log(i); // 10

✏️ 변수 호이스팅

let 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 동작합니다. let 키워드로 선언한 변수는 "선언 단계"와 "초기화 단계"가 분리되어 진행됩니다.

//초기화 단계 전인 선언 단계에서는 변수를 참조할 수 없다.
// 일시적 사각지대(TDZ Temporal Dead Zone)
console.log(foo); // ReferenceError: foo is not defined 선언 단계

let foo; // 초기화 단계
console.log(foo); // undefined

foo = 1; // 할당 단계
console.log(foo); // 1

✏️ 전역 객체와 let

var 키워드로 선언한 전역 변수와 전역 함수, 선언하지 않은 변수에 값을 할당한 암묵적 전역은 전역 객체 window의 프로퍼티가 됩니다.

// 브라우저 환경으로 가정

var x = 1; // 전역 변수
y = 2; // 암묵적 전역
function foo() {}; // 전역 함수

console.log(window.x); // 1 
console.log(x); // window 생략 가능

console.log(window.y); // 2
console.log(foo); // f foo() {}

let x = 1;
console.log(window.x); // undefined
console.log(x); // 1

let과 const 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아닙니다. 즉 위 예제의 window.x 와 같이 접근할 수 없습니다.

📚 const 키워드

const 키워드는 상수를 선언하기 위해 사용하지만 반드시 상수만을 위해 사용하지는 않습니다. const 키워드의 특징은 let 키워드와 대부분 동일합니다.

✏️ 선언과 초기화

const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 합니다.

const foo = 1;
// 선언만 할 경우 문법 에러가 발생한다.
const x; // SyntaxError

let 키워드로 선언한 변수와 마찬가지로 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생하지 않는 것처럼 동작합니다.

✏️ 재할당 금지

var또는 let 키워드로 선언한 변수는 재할당이 자유로우나 const 키워드로 선언한 변수는 재할당이 금지됩니다.

const foo = 1;
foo = 2; // TypeError

✏️ 상수

변수의 상대 개념인 상수는 재할당이 금지된 변수를 말합니다. const 키워드로 선언한 변수에 원시 값을 할당한 경우 변수 값을 변경할 수 없습니다.

상수는 상태 유지와 가독성, 유지보수의 편의를 위해 적극적으로 사용해야 합니다.

// 일반적으로 상수의 이름은 대문자로 선언해 명확히 나타낸다.
// 여러 단어로 이뤄진 경우에는 스네이크 케이스(_)로 표현한다.

// 상수로 지정해두면 세율이 변경 되었을때 상수만 변경하면 되기때문에 유지보수성이 향상된다.
const TAX_RATE = 0.1; 

let preTaxPrice = 100; // 세전 가격

let afterTaxPrice = preTaxPrice + (preTaxPrice * TAX_RATE); // 세후 가격

console.log(afterTaxPrice); // 110

✏️ const 키워드와 객체

const 키워드로 선언된 변수에 객체를 할당한 경우 값을 변경할 수 있습니다. 객체는 재할당 없이도 직접 변경이 가능하기 때문입니다.

const person = {
  name: 'lee'
};

person.name = 'kim'; // 재할당 없이 변경이 가능하다.

console.log(person); // {name: 'kim'}

const 키워드는 재할당을 금지할 뿐 불변을 의미하지는 않습니다.

📚 var vs. let vs. const

변수 선언에는 기본적으로 const를 사용하고 let은 재할당이 필요한 경우에 한정해 사용하는 것이 좋습니다. const 키워드를 사용하면 의도치 않은 재할당을 방지하기 때문에 조금 더 안전합니다. 재할당이 반드시 필요해진다면 let 키워드로 변경해 사용합니다.

0개의 댓글