icon안동민 개발노트

let, const와 블록 스코프


 ES6에서 도입된 letconst는 자바스크립트의 변수 선언 방식과 스코프 규칙을 크게 변화시켰습니다.

 이 절에서는 이러한 새로운 키워드와 블록 스코프의 개념에 대해 자세히 알아보겠습니다.

var, let, const 비교

 1. 스코프

  • var : 함수 스코프 또는 전역 스코프
  • let, const : 블록 스코프
if (true) {
   var x = 10;
   let y = 20;
   const z = 30;
}
console.log(x); // 10
console.log(y); // ReferenceError
console.log(z); // ReferenceError

 2. 호이스팅

  • var : 선언이 호이스팅됨, 초기화는 undefined
  • let, const : 선언만 호이스팅됨, 초기화되지 않음 (TDZ 영향)
console.log(a); // undefined
var a = 5;
 
console.log(b); // ReferenceError
let b = 10;

 3. 재선언

  • var : 동일 스코프 내 재선언 가능
  • let, const : 동일 스코프 내 재선언 불가
var x = 1;
var x = 2; // 가능
 
let y = 1;
let y = 2; // SyntaxError

 4. 재할당

  • var, let : 재할당 가능
  • const : 재할당 불가 (객체의 내부 속성은 변경 가능)
const obj = { prop: 42 };
obj.prop = 43; // 가능
obj = {}; // TypeError

블록 스코프

 블록 스코프는 {}로 둘러싸인 영역 내에서만 유효한 스코프입니다.

 letconst의 도입으로 자바스크립트에서도 블록 스코프를 사용할 수 있게 되었습니다.

 해결 가능한 문제들

  1. 루프 카운터 변수의 누출
for (let i = 0; i < 5; i++) {
   // i는 이 블록 내에서만 유효
}
console.log(i); // ReferenceError
  1. 클로저 내 변수 캡처 문제
let funcs = [];
for (let i = 0; i < 5; i++) {
   funcs.push(() => i);
}
console.log(funcs[2]()); // 2 (var였다면 5)

Temporal Dead Zone (TDZ)

 TDZ는 변수가 선언되었지만 아직 초기화되지 않은 상태를 말합니다.

console.log(x); // ReferenceError
let x = 5;

 letconst로 선언된 변수는 선언부터 초기화까지의 구간이 TDZ에 있어, 이 구간에서 접근하면 에러가 발생합니다.

const와 불변성

 const는 변수의 재할당을 방지하지만, 객체나 배열의 내부 값 변경은 막지 못합니다.

const arr = [1, 2, 3];
arr.push(4); // 가능
arr = [1, 2, 3, 4]; // TypeError
 
const obj = { x: 1 };
obj.y = 2; // 가능
obj = { x: 1, y: 2 }; // TypeError

 완전한 불변성을 위해서는 Object.freeze()를 사용할 수 있습니다.

const obj = Object.freeze({ x: 1 });
obj.x = 2; // 작동하지 않음 (엄격 모드에서는 에러)
console.log(obj.x); // 1

 단, Object.freeze()는 얕은(shallow) 동결만 수행합니다. 중첩된 객체의 완전한 불변성을 위해서는 재귀적인 동결이 필요합니다.

모범 사례와 가이드라인

  1. 기본적으로 const 사용, 재할당이 필요한 경우에만 let 사용
  2. var 사용 지양
  3. 반복문의 카운터 변수로 let 사용
  4. 전역 변수 사용 최소화
  5. 변수는 사용 범위에 가깝게 선언

var를 사용한 코드 리팩토링

  1. varconst로 변경하고, 재할당이 필요한 경우에만 let으로 변경
  2. 블록 스코프를 고려하여 변수 선언 위치 조정
  3. 호이스팅에 의존한 코드 구조 개선

 주의점

  • 기존 코드의 동작이 변경될 수 있으므로 테스트 필수
  • 클로저나 루프에서 변수 캡처 방식 변경 확인

개발 방식과 코드 품질에 미친 영향

  1. 향상된 코드 가독성 : 변수의 스코프가 더 명확해짐
  2. 버그 감소 : 의도치 않은 변수 재선언이나 변경 방지
  3. 더 안전한 코드 : const 사용으로 불변성 강화
  4. 성능 최적화 가능성 : 컴파일러가 블록 스코프 정보를 활용할 수 있음
  5. 모듈화 용이 : 블록 스코프로 인해 작은 단위의 코드 블록 설계 가능

 letconst의 도입, 그리고 블록 스코프의 지원은 자바스크립트 언어의 중요한 진화입니다. 이러한 변화는 개발자들이 더 안전하고 예측 가능한 코드를 작성할 수 있게 해주었습니다.

 블록 스코프의 도입으로 변수의 생명주기를 더 정확하게 제어할 수 있게 되었고, 이는 특히 대규모 애플리케이션에서 변수 관리를 용이하게 만들었습니다. Temporal Dead Zone의 개념은 개발자들이 변수 사용에 더욱 주의를 기울이게 하여, 잠재적인 버그를 사전에 방지할 수 있게 되었습니다.

 const의 사용은 불변성 프로그래밍 패러다임을 자바스크립트에서 더 쉽게 적용할 수 있게 해주었습니다. 이는 함수형 프로그래밍 기법의 활용을 촉진하고, 부작용을 줄이는 데 기여했습니다.

 이러한 변화들은 전반적으로 자바스크립트 코드의 품질을 향상시키는 데 큰 역할을 했습니다. 개발자들은 더 명확하고 안전한 코드를 작성할 수 있게 되었고, 이는 유지보수성과 확장성이 높은 애플리케이션 개발로 이어졌습니다.

 그러나 이러한 새로운 기능들을 효과적으로 활용하기 위해서는 개발자들의 학습과 기존 코드의 리팩토링이 필요합니다. 특히 레거시 코드베이스를 다룰 때는 var, let, const의 차이점을 정확히 이해하고 적절히 적용하는 것이 중요합니다.

 결론적으로, let, const, 그리고 블록 스코프의 도입은 자바스크립트를 더 강력하고 안전한 언어로 발전시켰습니다. 이러한 기능들을 적절히 활용함으로써, 개발자들은 더 높은 품질의 코드를 작성하고, 궁극적으로 더 나은 소프트웨어를 개발할 수 있게 되었습니다.