본문 바로가기
학습/Node.js

Var, Let, Const 차이점

코동이 2021. 5. 25.

자바스크립트의 변수 선언을 공부하다가 3가지가 있음을 알았습니다. 기존에는 var만 사용했는데, ES6 이후에는 letconst가 새롭게 추가되었고 var는 이제 잘 사용하지 않는다고 합니다. 차이점을 비교해보겠습니다.

Var

ES6 등장 이전에, var 선언이 규칙이었습니다. 하지만, var 사용은 몇 가지 문제가 있습니다. 그 문제 때문에 varletconst의 등장으로 이어졌습니다.

var의 Scope

 Scope는 해당 변수들이 어디 범위에서 사용이 가능한지를 의미합니다. var전역 범위이거나 함수/지역 범위입니다.

 

 var가 함수 밖에서 선언되면 전역 범위입니다. 즉, 함수 밖에서 var로 선언된 어떠한 변수들도 전체 window에서 사용이 가능하다는 것을 의미합니다.

 

var는 함수 안에 정의가 되면, 함수 범위입니다. 즉, 함수 내에서만 사용이 가능하고 접근이 가능합니다.

 

var tester = "hey hi";
    
function newFunction() {
    var hello = "hello";
}
console.log(tester); // hey hi
console.log(hello); // error: hello is not defined

 

tester는 함수 밖에 선언되었으므로 전역 범위이고 정상적으로 출력이 됩니다.

하지만, hello는 함수 내에 선언되었으므로 함수 범위이고 전역에는 설정되지 않아 에러가 납니다.

 

var 변수는 다시 선언되거나 수정될 수 있습니다.

 

*재선언

var greeter = "hey hi";
var greeter = "say Hello instead";

*수정

var greeter = "hey hi";
greeter = "say Hello instead";

 

var Hoisting

Hoisting은 변수들과 함수 선언이 코드 실행 이전에 변수 범위에서 가장 맨 위로 이동하는 것을 의미합니다.

 

console.log (greeter);
var greeter = "say hello"

 

위와 같이 코드를 작성했다면, 실행 시 아래와 같은 형태로 바뀝니다.

 

var greeter;
console.log(greeter); // greeter is undefined
greeter = "say hello"

 

따라서 var 변수는 undefined 값을 출력하면서 초기화되고 범위에서 맨 위에 선언됩니다.(hoisted 됩니다)

 

var의 단점

var greeter = "hey hi";
var times = 4;

if (times > 3) {
    var greeter = "say Hello instead"; 
}
    
console.log(greeter) // "say Hello instead"

 

times > 3true이기 때문에 greeter 값은 "say Hello instead"로 재정의 됩니다. 사용자가 greeter가 재정의 되었다는 사실을 안다면 상관이 없지만, 변수 greeter가 이미 이전에 선언되었다는 사실을 알지 못한다면 문제가 될 수 있습니다.

 

만약 다른 코드에서 greeter를 사용했었다면, 다른 결괏값에 당황할 수도 있습니다. 따라서 letconst가 등장했습니다.

 

Let

이제 변수 선언에 letvar 선언보다 개선되었습니다. 또한 우리가 위에서 보았던 var의 문제를 해결할 수 있습니다.

 

let은 block 범위

block은 {}로 구분된 코드 덩어리입니다. block은 중괄호의 범위입니다.

 

따라서 let으로 선언된 변수는 그 block 안에서만 유일하게 사용이 가능합니다

 

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

 

block 밖에서 hello를 사용하는 것은 에러입니다. hello는 if문 안의 범위에서만 유효하기 때문입니다.

 

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"

 

에러가 나지 않는 이유는, 같은 변수를 사용했고 let으로 선언했지만 범위가 다르기 때문입니다

 

따라서 var보다는 let이 더 나은 선택입니다. let을 사용할 때, 변수가 범위 내에만 존재하기 때문에, 이전에 변수의 이름을 사용했는지 아닌지 고민하지 않아도 됩니다. 

 

또한, 변수는 범위 내에서 2번 이상 선언될 수 없기 때문에, 이전에 var에서 문제라고 다룬 부분이 더 이상 문제가 되지 않습니다. ( 같은 범위 내에서 재선언이 가능하기 때문에 헷갈릴 여지가 있었습니다.)

 

Hoisting of let

var와 같이, let 선언은 맨 위로 이동합니다(hoisted 됩니다) undefined로 초기화되었던 var와는 달리, let 키워드는 undefined로 초기화되지 않습니다. 따라서 정의하기 이전에 let 변수를 사용하려고 한다면, 참조 에러를 발생합니다.

 

Const

const로 선언되는 변수들은 상수 값을 가집니다. const 선언은 let 선언과 공통점이 있습니다

 

const 선언은 block 범위입니다

let 선언과 같이, const 선언은 선언된 block에서만 접근이 가능합니다

 

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의 값은 수정됩니다.

 

Hoisting of const

let과 같이, const 선언은 맨 위로 hoisted 되지만, 초기화되지 않습니다.

 

- var 선언은 전역 범위이거나 함수 범위입니다. 반면 letconst는 block 범위입니다

- var 변수는 범위 내에서 수정될 수 있고 재선언 될 수 있습니다; let 변수는 수정될 수 있지만, 재선언 될 수 없습니다; const 변수는 수정될 수도, 재선언 될 수도 없습니다.

- 3가지 모두 해당 범위 내에서 맨 위로 hoisted 됩니다. var 변수가 undefined로 초기화되는 반면에, letconst 변수들은 초기화되지 않습니다.

- varlet은 초기화되지 않고도 선언될 수 있지만, const는 선언할 때 초기화되어야 합니다.

 

 

*참고

https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/

반응형