var를 지양하자

ljjunh·2024년 9월 30일

clean-code-javascript

목록 보기
1/38
post-thumbnail

1. var의 시대는 끝났다? ⚠️

  • ES2015 이전에는 var만 사용할 수 있었다. 하지만 var은 다음과 같은 문제점들을 가지고 있어 현대 Javascript에서는 지양해야 한다.
    1. 예측 불가능한 스코프 : 함수 스코프만을 가져 블록 레벨의 스코프 제어가 불가능
    2. 의도치 않은 전역 객체 생성 : 함수 외부에서 선언 시 전역 객치(window, global)의 속성이 됨
    3. 중복 선언 허용 : 같은 변수를 여러 번 선언해도 에러가 발생하지 않음
    4. 호이스팅으로 인한 혼란 : 선언 전에도 접근 가능한 동작이 코드의 흐름을 예측하기 어렵게 함

var의 특징

// 재선언 가능
var name = "이름";
var name = "이름2"; // 중복 선언 가능 - 버그 발생 위험

console.log(name); // '이름2'

// 호이스팅(선언과 할당이 분리. 선언만 끌어올려지고, 할당은 원래 위치에서 실행)
console.log(foo); // undefined - 호이스팅으로 인한 혼란
var foo = '안녕';

// 위코드는 내부적으로 다음과 같이 실행 됨
var foo; // 호이스팅
console.log(foo); // undefined
foo = "안녕"; // 초기화

이런 특징들 때문에 예상치 못한 버그가 발생하기 쉬웠다. 특히 큰 규모의 프로젝트에서는 변수가 어디서 어떻게 사용될지 추적하기가 매우 어려웠다.

2. let과 const의 등장 ✨

ES2015에서 도입된 letconst가 이러한 문제점들을 해결했다.

let의 특징

// 1. 재선언 불가
let name = "이름1";
let name = "이름2"; // SyntaxError: 중복 선언 방지

// 2. 재할당 가능
let name = "이름1";
name = "이름2";
name = "이름3";
console.log(name); // '이름3'

// 3. 선언만 따로 가능
let name;
name = "이름1";
console.log(name); // '이름1'

const의 특징

// 1. 재선언 불가
const name = "이름";
const name = "이름2"; // SyntaxError: Identifier 'name' has already...

// 2. 재할당 불가
const name = "이름";
name = "이름2"; // TypeError: Assignment to constant variable

// 3. 선언과 동시에 초기화 필수
const name; // SyntaxError: Missing initializer in const declaration

3. 스코프 차이 🔍

// 1. var는 함수 스코프
function example(){
	var x = 1;
  if (true){
  	var x = 2; // if는 블록이라 함수스코프를 가진 var는 상위에 있는 x를 재할당
    console.log(x); // 2
  }
  console.log(x); // 2
}

// 2. let, const는 블록 스코프
function example(){
  let x = 1;
  if (true){
  	let x = 2; // let, const는 블록스코프를 가져서 새로운 지역변수를 생성
    console.log(x); // 2
  }
  console.log(x); // 1
}

4. TDZ(Temporal Dead Zone) ⚡

let과 const는 TDZ라는 특별한 특성을 가진다. TDZ는 '일시적 사각지대'라고 직역할 수 있고 선언문이 실행되기 전까지는 어떤 방법으로도 접근할 수 없다.

먼저 var를 사용했을 때를 봐보자

console.log(name); // undefined
var name = '이름';

선언되기 전에도 접근이 가능하다. 하지만 let이나 const를 사용하면?

console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name = '이름';

에러가 발생한다. 이게 바로 TDZ의 영향이다.

왜 이런 차이가 있을까? 🧐
var의 경우

  • 호이스팅 발생 시 undefined로 자동 초기화
  • 어디서든 접근 가능(제한 없음)

let, const의 경우

  • 호이스팅은 되지만 초기화 전까지는 TDZ에 갇힘
  • 변수 선언 전에 접근하면 에러 발생

TDZ가 왜 필요할까? 🌟

  1. 버그 예방 : 변수 선언 전 사용 방지
  2. 코드 품질 : 더 명확하고 예측 가능한 코드 작성 가능
  3. 안정성 : 의도치 않은 변수 사용 방지

5. var를 지양해야 하는 구체적 이유 🚫

  1. 디버깅의 어려움
var x = 1;
// ... 1000줄의 코드가 있다고 가정
var x = 2; // 어디서 값이 변경되었는지 추적하기 어려움
  1. 스코프 오염
function badExample(){
	for (var i = 0; i < 5; i ++){
    	// i는 함수 전체에서 접근 가능
    }
  	console.log(i); // 루프 밖에서도 i에 접근 가능 - 의도치 않은 동작
}
  1. 비동기 처리의 문제
for (var i = 0; i < 3; i ++){
	setTimeout(()=> console.log(i), 1000)
  	// 3, 3, 3 출력
  	// 함수스코프라서 3번의 루프 모두 같은 i 를 바라봄
  	// let을 사용하면 반복마다 새로운 i가 만들어져서 1, 2, 3 출력
}
  1. 전역 객체 오염
var global = '전역변수'
console.log(window.global); // 브라우저 전역 객체 오염

6. 권장사항 🎯

  1. 기본적으로 const 사용
  2. 재할당이 필요한 경우에만 let 사용
  3. var는 레거시 코드가 아니라면 사용하지 않기
  4. React나 Next에서 컴포넌트 상태관리 할 때는 주로 const사용
profile
Hello

0개의 댓글