var를 지양해야 하는 이유

hyun·2022년 3월 13일
1

JS 

목록 보기
1/5
post-thumbnail

이 포스트에서 다룰 것

프로그래밍 언어를 공부할 때 제일 먼저 배우는 것이 변수 선언이다. JS를 공부하면서 var 사용을 지양하라는 말을 들어보았고, 프론트엔드 면접을 준비하면 var, let,const의 차이가 무엇인지 묻는 단골 질문도 공부했다. 그런데 왜 쓰면 안 되는데? 에 대한 질문엔 정확히 대답할 수 없었다. 지금까지는 남들이 쓰지 말라고 하니까 안 썼지만, 이제 쓰면 안 되는 정확한 이유를 알아야겠다.

letconst는 ES 2015 버전부터 생겼다고 한다. 그래서 그 이전에는 어쩔 수 없이 var 키워드를 통해서 변수를 생성할 수 있었다. var로는 부족했기 때문에 이를 보완하기 위한 더 좋은 것들이 나온 것일 텐데, 어떤 점이 개선되었을까?

  • var, let,const는 재선언&재할당 가능 여부의 차이가 있다.
  • var는 함수 스코프, let&const는 블록 단위 스코프를 가진다.
  • letconst는 Temporal Dead Zone(TDZ)이라는 속성을 가진다.

이번 포스트에서는 위의 특징들을 알아볼 것이다.

var, let, const

var

다음의 코드를 살펴보자.

var name = "hyun";
var name = "hyun2";

같은 이름의 변수에 다른 값을 할당했는데도 선언이 잘 된다.

var name = "hyun";
var name = "hyun2";
var name = "hyun";

console.log(name) // hyun

위 코드는 같은 이름의 변수에 값까지 똑같이 넣었다. 이 상태에서 변수를 호출해 보면 가장 마지막에 할당된 값 hyun이 나오게 된다. var는 재할당, 재선언이 가능하다. 복잡한 프로젝트에서 재할당, 재선언이 가능한 변수를 계속해서 사용한다면 분명히 문제가 생길 것이다. 사용이 자유로운 만큼 문제의 소지는 많아진다.

let

let name = "hyun";
let name = "hyun";

var에서 해봤던 것처럼 let에 같은 변수명에 같은 값을 넣어보았다.
바로 에러를 뿜는다.
let은 이미 선언한 변수를 쓸 수 없다.

let name;
name = "hyun";
name = "hyun2";
name = "hyun3";

이 코드는 에러를 내지 않는다. let은 선언 후 재할당이 가능하기 때문이다.

const

const name;
name = "hyun";
name = "hyun2";
name = "hyun3";

위의 코드를 const로 바꾸면 바로 에러가 난다.
const로 변수를 선언하게 되면 할당까지 해야 에러가 나지 않는다. 즉 const는 변수를 한번 만들고 재할당을 할 수 없다.

Scope

첫 번째로는 세 가지 변수 키워드의 선언과 할당 부분에서 차이를 알아보았다. 그럼 두 번째로 언급한 scope의 차이를 알아보자.

Function Scope

var global = "전역";
if (gloabl == "전역"){
	var global = "지역";
	console.log(global); // 지역
}

전역변수를 사용하지 말라는 이야기 또한 많이 들어보았을 것이다(하면 안되는게 참 많다). 위의 코드에서는 변수 globalvar 키워드로 선언 및 초기화하였고, if문 안에서 재선언 및 재할당하였다. if문 안의 console.log의 결과는 "지역"이다. if문 중괄호 안에 있으니까 당연한 결과다.

var global = "전역";
if (gloabl == "전역"){
	var global = "지역";
	console.log(global); // 지역
}

console.log(global); // 지역

그러면 if문의 중괄호 밖에서 console을 찍어 보면 어떻게 될까? if문을 벗어났으니까 "전역"이 나올 것이라고 기대하지만, 놀랍게도 결과는 여전히 "지역"이다. if문 안에서 재할당한 값이 전역 scope까지 적용된 것이다.

왜?

이유는 var는 함수 단위 scope를 가지기 때문이다. if문은 함수가 아니기 때문에 전역공간의 변수까지 오염이 되어버렸다. var를 쓰지 말아야 하는 이유가 점점 납득이 가기 시작한다. 프로젝트 상황에서, 많은 라인의 코드에서 이런 일이 발생한다면 끔찍하다.

Block Scope

let global = "전역";
if (gloabl == "전역") {
	let global = "지역";
	console.log(global); // 지역
}

console.log(global); // 전역

letconst는 블록 단위 scope를 가지기 때문에 마음이 편안한 결과가 나온다. 지역 변수로서의 역할을 충실하게 수행해준다.

let global = "전역";
{
	let global = "지역";
	console.log(global); // 지역
}

console.log(global); // 전역

심지어 이렇게 중괄호만 있어도 원하는 결과를 보여준다. var 보다 훨씬 안전하게 사용할 수 있다.

var보다는 let, let보다는 const

재할당이라는 키워드에 초점을 맞춰 보자. const는 어떻게 값을 바꿀 수 있을까?

객체 실험

// 선언, 할당
const person = {
  name: "hyun",
  age: 27,
}


// 재할당이 불가능하므로 아래의 코드는 에러
person = {
  name: "hyun2",
  age: 20
}

// 변수의 값을 바꿔보자
person.name = "hyun2";
person.age = 20;

console.log(person)

재할당이 불가능한 것을 확인하고, 해당 부분을 주석처리 한 후 다시 실행해보면 변수 값이 잘 바뀐 것을 확인할 수 있다. person.name = "hyun2";가 잘 동작하는 이유는 무엇일까? 변수를 재할당하지 않고 객체 내부의 값만 바꾼 것이기 때문이다.

배열 실험

const person = [{
    name: "hyun",
    age: 27,
  }]
  
person.push({name: "hyun3", age: 34});
console.log(person) // [ { name: 'hyun', age: 27 }, { name: 'hyun3', age: 34 } ]

이 또한 잘 동작한다! const는 재할당만 금지된다. 객체, 배열의 레퍼런스 값을 조작할 때는 문제가 없다는 뜻이다. var이나 let을 사용해서 변수를 재할당하지 않아도, const로도 변수 내부의 값을 변경할 수 있으므로 제일 안전한 const를 쓰는 것을 권장한다고 한다.

정리

키워드재선언재할당scope
var가능가능함수
let불가능가능블럭
const불가능불가능블럭
profile
프론트엔드를 공부하고 있습니다.

0개의 댓글