let, const 키워드와 블록 레벨 스코프

이보아·2024년 5월 22일
0

모던_자바스크립트

목록 보기
10/18
post-thumbnail

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

변수 중복 선언 허용

var 키워드로 선언한 변수는 중복 선언이 가능하다.

var x = 1;
var y = 1;

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

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

함수 레벨 스코프

var 는 함수가 아닌 공간에서 선언한 경우, 모두 전역 변수처럼 동작한다.

var x = 1;

// x는 전역 변수이다. 이미 선언된 x가 있는데도 중복 선언된다. -> 의도치 않게 변수값이 변경 되는 부작용이 생김
if (true) x = 10; 

console.log(x); // 10
var i = 10;

// i는 전역 변수이다. 이미 선언된 i가 있는데도 중복 선언된다. -> 의도치 않게 변수값이 변경 되는 부작용이 생김
for (var i = 0; i < 5; i--) console.log(i);

console.log(i); // 5

변수 호이스팅

var 키워드로 선언한 경우, 변수 선언문이 최하단에 있는데도 불구하고 최상단에 있는 것 처럼 동작한다.

console.log(foo); // undefined

foo = 123;

console.log(foo); // 123

var foo;

let 키워드

변수 중복 선언 금지❗

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

var foo = 123;
var foo = 456;

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

블록 레벨 스코프

var 와 달리 letif 문, for 문, try` 코드 블록에서도 스코프를 갖기 때문에 외부에서 접근이 불가능해진다.

if (true) {
  var x = 1;
  let a = 1;
}

console.log(x); // 1
console.log(a); // ReferenceError: a is not defined

변수 호이스팅

let 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는다.

호이스팅 - 변수 선언문이 최하단에 있는데도 불구하고 최상단에 있는 것 처럼 동작

console.log(foo); // ReferenceError: foo is not defined
let foo = 123;

var 키워드는 런타임 이전에 선언과 동시 초기화를 진행하는데, 이때 즉시 undefined로 초기화해버린다. 따라서, 값 할당은 런타임에 이루어지면서 문제가 된다.
차이점이라고 하면 let 은 선언과 초기화가불리되어 진행된다. 아직 초기화 되지 않은 변수를 참조했다는 에러를 발생하게 만드는 것이다.

이 때, 선언 후 초기화가 아직 이루어지지 않은 구간은 일시적 사각지대(TDZ, Temporal Dead Zone)이라 부른다.

  • let은 호이스팅이 되지 않음
let foo = 4;
{
  console.log(foo); // ReferenceError: Cannot access 'foo' before initilization
  let foo = 123;
}

전역 객체와 let

var 로 변수 선언하거나 함수를 정의한 경우, 또는 선언하지 않고 할당을 진행하는 암묵적 전역은 전역 공간의 프로퍼티가 된다.

따라서, 브라우저 환경에서는 window 객체를 통해 접근하게 되는데, 이는 생략 가능하다.

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

let a = 4;

// var 키워드로 선언한 전역 변수는 전역 객체 window의 프로퍼티이다. 
console.log(window.x); // 1
// 전역 객체 window의 프로퍼티는 전역 변수처럼 사용 가능
console.log(x); // 1

// 암묵적 전역은 전역 객체 window의 프로퍼티
console.log(window.y); // 2
console.log(y); // 2

// 함수 선언문으로 정의한 전역 함수는 전역 객체 window 프로퍼티이다. 
console.log(window.foo); // f foo() {}
// 전역 객체 window의 프로퍼티의 전역 변수처럼 사용 가능 
console.log(foo); // f foo() {}

const 키워드

const 키워는 상수를 선언하기 위해 사용한다.

선언과 초기화

const i = 1;
const j; // SyntaxError: Missing initializer in const delcaration

👉 const 키워드는 let 과 달리 선언과 동시에 초기화를 진행해야 한다.
let 과 동일하게 블록 스코프를 가지고 호이스팅과 관련한 동작도 동일하게 이루어진다. (TDZ 존이 존재)

재할당 금지

const 키워드로 선언한 경우, 재할당이 금지 된다.

const foo = 1;
foo = 2; // TypeError: Assignemt to constant variable

상수

재할당이 금지된 변수를 의미함
👉 유지와 가독성, 유지보수의 편의를 위해 적극적으로 사용 권장

// 세율을 의미하는 0.1은 변경할 수 없는 상수로서 사용할 값
// 변수 이름을 대문자로 선언해 상수임을 명확히 나타낸다. 
const TAX_RATE = 0.1;

let preTaxPrice = 100;

let afterTaxPrice = preTaxPrice + preTaxPrice * TAX_RATE;

console.log(afterTaxPrice);

const 키워드와 객체

const 키워드로 선언된 변수에 객체를 할당한 경우 값을 변경할 수 있다.
👉 const 키워드 재할당을 금지할 뿐 "불변"을 의미하지는 않음

const person = {
  name: "Lee",
};

person.name = "KIM";

console.log(person); // {name: "KIM"}
}

var vs. let vs. const

  • ES6를 사용한다면 var을 사용하지 말자
  • 재할당이 필요한 경우에 한정해 let 키워드를 사용한다. 스코프는 최대한 좁게 만든다.
  • 변경이 발생하지 않고 읽기 전용으로 사용하는 원시 값과 객체에는 const 키워드를 사용한다.
profile
매일매일 틀깨기

0개의 댓글