Original article: Var, Let, and Const – What's the Difference?
ES2015(ES6)에서 반짝이는 새로운 기능들이 많이 등장했습니다. 2020년이 된 지금, 많은 JavaScript 개발자들이 그 기능들을 사용하기 시작했을 것이며 또 익숙해졌을텐데요. 여전히 그 중 몇몇은 일부 개발자들에게 미스터리로 남아있을 수 있습니다.
ES6에 포함된 기능 중 하나는 변수 선언에 사용할 수 있는 let
및 const
의 추가입니다. 지금껏 애용해온 var
와 다른 점은 무엇일까요? 이 글은 여전히 명확히 이해하지 못 한 당신을 위한 것입니다.
Var
ES6의 등장 이전에는 문제점들이 있음에도 불구하고 var
로 변수를 선언하는 것이 지배적이었는데요. 따라서 새로운 변수 선언 방식이 등장할 수밖에 없었습니다. 우선, 문제점에 대해 논의하기 전에 var
자체에 대해 더 이해해봅시다.
Scope of var
범위는 기본적으로 변수를 사용할 수 있는 위치를 의미합니다. var
선언은 전역 범위 혹은 함수 범위로 지정됩니다.
var
변수가 함수 외부에서 선언될 때의 범위는 전역입니다. 즉, 함수 블록 외부에서 var
를 사용하여 선언된 모든 변수를 전체 윈도우 상에서 사용할 수 있는 것이죠.
var
가 함수 내에서 선언될 때는 함수 범위로 지정됩니다. 즉, 해당 함수 내에서만 사용하고 접근할 수 있습니다.
자세한 이해를 돕기위해 아래의 예제를 살펴봅시다.
var greeter = "hey hi";
function newFunction() {
var hello = "hello";
}
여기서 hello
가 함수 범위인 반면에, greeter
는 함수 밖에 존재하므로 전역 범위를 가지게 됩니다.
var tester = "hey hi";
function newFunction() {
var hello = "hello";
}
console.log(hello); // error: hello is not defined
hello
는 newFunction()
함수 밖에서 사용할 수 없기 때문에 에러가 발생하게 됩니다.
var 변수는 재선언되고, 업데이트될 수 있습니다.
같은 범위 내에서라면 아래의 두 경우와 같이 수정이 가능하며 에러가 발생하지 않습니다.
var greeter = "hey hi";
var greeter = "say Hello instead";
var greeter = "hey hi";
greeter = "say Hello instead";
var의 호이스팅
호이스팅이란 변수와 함수 선언이 맨 위로 이동되는 자바스크립트 매커니즘인데요. 아래와 같이 코드를 짜면:
console.log (greeter);
var greeter = "say hello"
자바스크립트는 다음과 같이 해석하기 때문에:
var greeter;
console.log(greeter); // greeter is undefined
greeter = "say hello"
var
변수는 범위 내에서 맨 위로 올려지고, 값은 undefined(정의되지 않음)
으로 초기화됩니다.
var의 문제점
아래의 예제를 토대로 var
를 사용할 시 따라오는 취약점에 대해 이야기해보겠습니다.
var greeter = "hey hi";
var times = 4;
if (times > 3) {
var greeter = "say Hello instead";
}
console.log(greeter) // "say Hello instead"
time > 3
가 true
를 반환하기 때문에 greeter
는 "say Hello instead"
로 재정의됩니다. 의도적으로 재정의한 것이라면 괜찮겠지만, 변수 greeter
가 이미 정의되어 있다는 사실을 인식하지 못한 경우에는 문제가 됩니다.
만약 코드의 다른 부분에서 greeter
를 사용한 적이 있다면 뜻밖의 출력 결과에 놀랄 수 있습니다. 그리고 많은 버그를 발생시킬 수 있기 때문에 let
과 const
가 필요하게 된 것이죠.
Let
var
선언에 대한 개선을 반영한 let
이 현재 변수 선언에서 선호되고 있습니다. 방금 다뤘던 var
의 문제점을 해결할 수 있었던 이유에 대해 살펴봅시다.
블록 범위 let
블록은 {}
로 바인딩된 코드 청크인데요. 하나의 블록은 중괄호 속에서 존재하며, 중괄호 안에 있는 것은 모두 블록 범위입니다.
let
으로 선언된 변수는 해당 블록 내에서만 사용가능합니다. 예를 들어 설명하자면:
let greeting = "say Hi";
let times = 4;
if (times > 3) {
let hello = "say Hello instead";
console.log(hello);// "say Hello instead"
}
console.log(hello) // hello is not defined
중괄호로 감싸진 hello
변수가 정의된 블록 외부에서 helllo
를 사용했더니 에러가 반환되는 것을 확인할 수 있습니다. let
변수는 블록 범위이기 때문이죠.
let은 업데이트될 수 있지만, 재선언은 불가능하다.
var
와 마찬가지로 let
으로 선언된 변수는 해당 범위 내에서 업데이트될 수 있습니다. 하지만, var
와 달리 let
변수는 범위 내에서 다시 선언할 수 없습니다. 아래의 기능이 작동하는 동안:
let greeting = "say Hi";
greeting = "say Hello instead";
이와 같은 에러가 발생합니다:
let greeting = "say Hi";
let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared
그러나 동일한 변수가 다른 범위 내에서 정의된다면, 에러는 더 이상 발생하지 않습니다.
let greeting = "say Hi";
if (true) {
let greeting = "say Hello instead";
console.log(greeting); // "say Hello instead"
}
console.log(greeting); // "say Hi"
오류가 없는 이유는 무엇일까요? 두 예제가 서로 다른 범위를 가지므로 서로 다른 변수로 취급되기 때문입니다. 따라서 var
보다 let
이 더 나은 선택이 될 수 있는 것이죠. let
을 사용하는 경우라면, 변수가 범위 내에서만 존재하기 때문에 이전에 이미 사용한 적이 있는 변수 명에 대해서 더 이상 신경쓰지 않아도 좋습니다.또한, 범위 내에서 동일한 변수를 두 번 이상 선언할 수 없기 때문에 앞서 설명한 var
의 문제가 발생하지 않습니다.
let의 호이스팅
var
와 마찬가지로 let
선언은 맨 위로 끌어올려집니다. undefined(정의되지 않음)
으로 초기화되는 var
와 다르게 let
의 키워드는 초기화되지 않습니다. 선언 이전에 let
변수를 사용하려고 시도한다면 Reference Error(참조 오류)
가 발생할 것입니다.
Const
const
로 선언된 변수는 일정한 상수 값을 유지합니다. const
선언은 let
선언과 몇 가지 유사점을 공유합니다.
블록 범위 const
let
선언처럼 const
선언도 선언된 블록 범위 내에서만 접근 가능합니다.
const는 업데이트도, 재선언도 불가능하다
const
로 선언된 변수의 값이 해당 범위 내에서 동일하게 유지됨을 의미합니다. 업데이트하거나 다시 선언할 수가 없는 것이죠. const
로 변수를 선언한 경우에는 다음과 같은 두 작업을 수행할 수 없습니다:
const greeting = "say Hi";
greeting = "say Hello instead";// error: Assignment to constant variable.
const greeting = "say Hi";
const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared
따라서 모든 const
선언은 선언하는 당시에 초기화되어야 합니다.
개체의 경우는 다소 다른 점이 있는데요. const
개체는 업데이트할 수 없지만, 개체의 '속성'은 업데이트할 수 있습니다. const
객체를 다음과 같이 선언했다면:
const greeting = {
message: "say Hi",
times: 4
}
아래와 같은 작업은 불가능하지만:
greeting = {
words: "Hello",
number: "five"
} // error: Assignment to constant variable.
다음의 코드는 가능합니다:
greeting.message = "say Hello instead";
오류를 반환하지 않고 greeting.message
값이 업데이트됩니다.
const의 호이스팅
let
과 마찬가지로 const
선언도 맨 위로 끌어올려지지만, 초기화되지는 않습니다.
세 가지 변수 선언법의 차이점에 대해서 총정리하자면:
var
선언은 전역 범위 또는 함수 범위이며,let
과const
는 블록 범위이다.var
변수는 범위 내에서 업데이트 및 재선언할 수 있다.let
변수는 업데이트할 수 있지만, 재선언은 할 수 없다.const
변수는 업데이트와 재선언 둘 다 불가능하다.- 세 가지 모두 최상위로 호이스팅된다. 하지만
var
변수만undefined(정의되지 않음)
으로 초기화되고let
과const
변수는 초기화되지 않는다. var
와let
은 초기화하지 않은 상태에서 선언할 수 있지만,const
는 선언 중에 초기화해야한다.
Var, Let, Const에 대한 설명 영상
이게 전부랍니다. 질문 혹은 추가해야할 내용이 있다면 알려주세요.
읽어주셔서 감사합니다 :)