Posts [JavaScript] var, let, const 차이
Post
Cancel

[JavaScript] var, let, const 차이

JavaScript에는 var, let, const 세 가지로 변수 선언을 할 수있다. 각각의 차이점에 대해 알아보자.

1. 변수 선언 방식

var 변수는 재선언이 가능하다.

1
2
3
4
5
var name = "joojaewoo";
console.log(name); // joojaewoo

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

변수를 한 번 더 선언했음에도 불구하고, 서로 다른값이 잘 출력된다. 유연하게 사용될 수도 있지만, 코드량이 많아진다면 어디서 선언되었고 어떻게 사용되는지 파악하기 힘들 뿐 아니라 값이 바뀔수도 있다.

letconst는 ES6이후 var을 보완하기 위해 추가된 변수 선언방식이다.

1
2
3
4
5
let name = "joojaewoo";
console.log(name); // joojaewoo

let name = "joo";
console.log(name); // Uncaught SyntaxError: Identifier 'name' has already been declared

name이 이미 선언되었다는 에러가 발생한다. letconst는 변수 재 선언이 불가능한 공통점을 가지고 있지만 둘의 차이점은 immutable 여부이다. let는 아래와 같이 변수에 재 할당이 가능하다.

1
2
3
4
5
let name = "joojaewoo";
console.log(name); //joojaewoo

name = "joo";
console.log(name); //joo

그러나 const는 재선언, 재할당이 모두 불가능하다.

1
2
3
4
5
const name = "joojaewoo";
console.log(name); // joojaewoo

name = "joo"; // Uncaught TypeError: Assignment to constant variable.
console.log(name);

2. 변수의 유효범위 (스코프)

스코프 ( Scope ) : 변수에 접근할 수 있는 범위 전역 스코프 : 말 그대로 전역에 선언되어있어 어느 곳에서든지 해당 변수에 접근할 수 있다는 의미 지역 스코프 : 해당 지역에서만 접근할 수 있어 지역을 벗어난 곳에선 접근할 수 없다는 의미

var 변수의 유효범위는 전역 스코프를 제외하면 오직 함수 스코프를 따른다.

1
2
3
4
5
6
7
8
var a = 1;
function print() {
  var a = 111;
  console.log(a); //111
}

print();
console.log(a); //1

print함수에서의 console.log(a);는 a를 출력하기위해 자신의 함수 스코프내의 변수 a를 찾아본다. var a =111;을 찾은 다음 이 값을 출력하면서 ‘111’이라는 값이 출력된다.

그러나 함수 단위의 스코프를 따르기 때문에 문제점도 발생한다.

1
2
3
4
for (var i = 0; i < 10; i++) console.log(i);
// 1 2 3 ... 9 한줄에 하나씩 순선대로 출력

console.log(i); // 9

반복문이 종료되었지만 var변수인 i는 함수 단위의 스코프를 사용하기 떄문에 i의 값이 유지되는 문제가 발생한다. 이처럼 var변수는 전역변수를 남발할 가능성을 높인다.

이를 해결하기 위해 letconst는 블록 레벨 스코프를 따른다.

1
2
3
4
5
6
7
let a = 1;
{
  let a = 2;
  let b = 2;
}
console.log(a); //  1
console.log(b); //  ReferenceError: b is not defined

블록 내에서 선언된 변수 a와 b는 지역변수이다. 전역에서 선언된 a 와 다른 별개의 변수이다. 따라서 전역 범위에서 b는 참조할 수 없고, a는 1을 가르킨다.

대부분의 문제는 전역변수로 인해 발생하는데, 유효범위가 넓어서 어디서 어떻게 사용될 것인지 파악하기 힘들며, 비 순수함수에 의해 의도하지 않게 변경될 가능성이 있어 복잡성을 증가시킨다. 따라서 변수의 스코프는 좁을수록 좋다.

Scope와 Scope Chain에 대해서는 다음에 자세히 포스팅 할 예정이다.

3. 호이스팅

호이스팅 ( Hoisting ) : 변수나 함수 선언문 등을 해당 스코프의 가장 최 상단으로 끌어올리는 것

자바스크립트는 모든 선언에 대해서 호이스팅을 한다.

하지만 var로 선언된 변수와 같이 let로 선언된 변수를 선언문 이전에 참조하면 ReferenceError이 발생한다

1
2
3
4
5
console.log(foo); // undedinfed
var foo;

console.log(bar); // Error: Uncaught ReferenceError: bar is not defined
let bar;

이는 let로 선언된 변수는 스코프의 시작에서 변수의 선언까지 TDZ에 빠지기 때문이다. 변수는 선언단계 => 초기화단계 => 할당단계에 걸쳐 생성되는데 var으로 선언된 변수는 선언과 초기화 단계가 한번에 이루어진다. 그러나 let로 선언된 변수는 선언단계와 초기화 단계가 분리되어 진행된다.

1
2
3
4
5
6
7
8
9
10
//스코프의 상단에서 선언단계가 실행된다.
// 아직 변수가 초기화(메모리 공간 확보) 되지않았다.

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

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 변수 할당문에서 할당 단계가 실행된다.
console.log(foo); //1

정리

변수 선언에는 많은 문제를 야기할 수 있는 var은 지양하고 기본적으로 const를 사용하고, 재 할당이 필요한 경우 let를 사용하는 것이 좋다. const는 의도치 않은 재할당을 방지해주기 때문에 의도치 않은 결과를 방지할 수있다.

This post is licensed under CC BY 4.0 by the author.

[프로그래머스] LV.4 징검다리 (JS)

[JavaScript] 자바스크립트 Scope

Comments powered by Disqus.