[JS] 자바스크립트 중급강좌 (feat. 코딩앙마) - 변수(var, let, const)

앱런칭 프로젝트와 앞으로 공부할 TypeScript, Nest.js를 위해서 JavaScript 문법에서 헷갈리는 부분이 몇군데 있어서 유튜브 코딩앙마님의 강의를 통해서 한번 정리를 해보려고 한다.

이번 포스팅에서는 변수에 대해서 헷갈리는 부분을 정리해보도록 하겠다.


(1) var vs let

  • var는 한번 선언된 변수를 다시 선언할 수 있다. 하지만 let은 한번 선언된 변수를 다시 선언할 수 없다.
var name = "Mike";
console.log(name);  // Mike

var name = "Jane";
console.log(name);  // Jane

let name2 = "kanguk";
console.log(name2);  // kanguk

let name2 = "jason";
console.log(name2);  // Error!
  • var는 선언하기 전에 사용할 수 있다. (에러발생x)
    하지만 let은 ReferenceError를 발생시킨다.
console.log(name);  // undefined
var name = "Mike";

이유는 위의 코드는 다음과 같이 작동하기 때문이다.

var name;
console.log(name);  // undefined 
name = "Mike";   // 할당

실제로 코드가 올라가는 것은 아니지만 최상위로 올라간 것처럼 동작한다.
이를 호이스팅(Hoisting) 이라고 한다.

Hoisting: 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 행동하는 것

또한 위의 코드에서는 console에서 undefined를 출력한다. 이유는 선언은 호이스팅이 되지만 할당은 호이스팅이 되지 않기 때문이다. name이라는 변수만 올려진 것이고 Mike라는 값은 그 자리에 있는 것이다.

같은 상황에서 let은 error를 발생시킨다고 하였다. let과 const도 var와 마찬가지로 hoisting을 하게 되는데 왜 var처럼 동작을 하지 않을까? 이유는 바로 TDZ 때문!

(2) Hoisting과 TDZ

  • TDZ는 Temporal Dead Zone의 약자이다.
  • TDZ에 있는 변수들은 사용할 수 없다. let과 const는 TDZ의 영향을 받는다. 즉, 할당을 하기 전에는 사용할 수 없는 것이다.
  • TDZ는 코드를 예측 가능하게 하고 잠재적인 버그를 줄일 수 있다.

let age = 30;

function showAge() {
	console.log(age); 
}

showAge();   // 30

위의 코드는 문제를 일으키지 않는다. 다음 케이스를 살펴보자.

let age = 30;

function showAge() {
	console.log(age); 
  	let age = 20;
}

showAge();   

다음 코드는 문제가 발생하게 된다. 이유를 살펴보도록 하자.
Hoisting은 Scope 단위로 일어나게 된다.

위의 코드에서 scope는 함수 내부를 말한다. let으로 선언한 2번째 age 변수가 hoisting을 일으키게 된다. 만약에 hoisting이 일어나지 않았다면 결과값이 30으로 나타났을 것이다.

(3) 변수의 생성과정

1. 선언 단계
2. 초기화 단계
3. 할당 단계

1) var


var는 선언과 초기화가 동시에 진행된다. 그래서 할당 전에 호출을 하게 되면 에러가 발생하지 않고 undefined가 출력된다.
(이 때, 초기화는 undefined를 할당 해주는 단계라고 생각하면 된다)

2) let


let은 선언과 초기화가 분리되어 진행된다. hoisting이 되면서 선언 단계가 진행되지만 초기화 단계는 실제 코드에 도달했을 때 진행되기 때문에 ReferenceError가 발생하는 것이다.

3) const


const는 선언과 할당이 동시에 진행되어야 한다. 따라서 다음 코드는 에러가 발생하게 된다.

let name;
name = 'Mike';

var age;
age = 30;

const gender;   // 에러 발생!
gender = 'male';

에러가 발생한 이유는 선언하면서 할당을 하지 않았기 때문이다.
따라서 위의 코드는 "const gender = 'male';"로 수정을 해야한다.

(4) 스코프 (scope)

스코프는 우리말로 번역하면 '범위'라는 뜻을 가지고 있다. 즉, 스코프는 '변수에 접근할 수 있는 범위'라고 할 수 있다.

var: 함수 스코프 (function-scoped)
let, const: 블록 스코프 (block-scoped) (함수, if문, for/while문 try/catch문)

const age = 30;
if (age > 19) {
	var txt = "성인"; 
}
console.log(txt);  // 성인

예를 하나 들어보자. 위의 코드에서 if문 안에 선언한 var 변수는 if문 밖에서도 사용이 가능하다. 하지만 let과 const는 var처럼 사용할 수 없다. let과 const는 블록 내에서만 사용이 가능하다. 이를 block-scope라고 한다.

function add(num1, num2) {
	var result = num1 + num2;  
}
add(2,3);
console.log(result);

var는 함수 내에서 선언되면 함수 밖에서 사용할 수 없다. 즉, 유일하게 벗어날 수 없는 스코프가 함수라고 생각하면 된다.

Scope에 관한 내용을 더 자세하게 알고 싶으면 다음 링크를 참고하면 좋을 것 같다.
https://velog.io/@mgm-dev/%EC%8A%A4%EC%BD%94%ED%94%84%EB%9E%80-%EB%AD%98%EA%B9%8C


이렇게 변수에 대해 헷갈리는 개념들을 정리해보았다. 앞으로 var는 사용하지 않고 const와 let을 사용하는 것이 좋다. 예측 가능한 결과를 내고 버그를 줄일 수 있기 때문이다!

(해당 포스팅의 내용은 유튜브 코딩앙마님의 영상을 참고했습니다)
Youtube: https://www.youtube.com/watch?v=4_WLS9Lj6n4

좋은 웹페이지 즐겨찾기