JS (15) - let, const 키워드와 블록 레벨 스코프

최조니·2022년 7월 4일
0

JavaScript

목록 보기
12/36

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

1) 변수 중복 선언 허용

  • var 키워드로 선언한 변수는 중복 선언 가능
    → 의도치 않은 값 변경이 일어날 수 있음
var x = 1;
var y = 1;

var x = 100;
var y;

console.log(x);		// 100
console.log(y);		// 1

2) 함수 레벨 스코프

  • 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

3) 변수 호이스팅

  • var 키워드로 선언한 변수는 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어올려진 것처럼 동작
    → 변수 호이스팅에 의해 에러를 발생하진 않지만, 프로그램 흐름상 맞지 않고 가독성을 떨어트리고, 오류를 발생할 여지가 있음
console.log(foo);	// undefined

foo = 123;
console.log(foo);	// 123

var foo;

15.2 let 키워드

var 키워드의 단점을 보완하기 위해 let, const 도입

1) 변수 중복 선언 금지

  • let 키워드로 선언한 변수는 중복 선언하면 문법 에러 발생
var foo = 123;
var foo = 456;

let bar = 123;
let bar = 456;	// SyntaxError: Identifier 'bar' has already been declared

2) 블록 레벨 스코프

  • let 키워드로 선언한 변수는 모든 코드 블록을 지역 스코프로 인정하는 블록 레벨 스코프를 따름
let foo = 1;

{
  let foo = 2;
  let bar = 3;
}

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

3) 변수 호이스팅

  • 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) 발생

4) 전역 객체와 let

  • 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

15.3 const 키워드

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

  • const 키워드의 특징은 let 키워드와 대부분 동일

1) 선언과 초기화

  • 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

2) 재할당 금지

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

3) 상수

  • 상수는 재할당이 금지된 변수

  • const 키워드로 선언한 변수에 원시 값을 할당한 경우 변수 값을 변경할 수 없음

const TAX_RATE = 0.1;

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

4) const 키워드와 객체

  • const 키워드로 선언한 변수에 원시 값을 할당한 경우 변수 값을 변경할 수 없음

  • 하지만, const 키워드로 선언한 변수에 객체를 할당한 경우 변수 값을 변경할 수 있음
    const 키워드는 재할당을 금지할 뿐 "불변"을 의미 X

  • 이때 객체가 변경되더라도 변수에 할당된 참조 값은 변경되지 않음

const person = {
  name: 'Lee'
};

person.name = 'Kim';
console.log(person);	// {name: "Kim"}

15.4 var vs. let vs. const

  • 변수 선언에 기본적으로 const를 사용하고,
    let은 재할당이 필요한 경우 한정해 사용하는 것이 좋음

  • 사용 권장

    • var : 사용을 권장하지 않음
    • let : 재할당이 필요한 경우에 한정, 변수의 스코프는 최대한 좁게
    • const : 변경이 발생하지 않고 읽기 전용으로 사용하는 원시 값과 객체
      → 재할당을 금지하므로 var, let 키워드보다 안전
profile
Hello zoni-World ! (◍ᐡ₃ᐡ◍)

0개의 댓글