본문으로 바로가기

[NodeJs] var, let, const 차이점

category 개발/노드 JS 2019. 1. 24. 22:12

var, let, const

var, let 변수를 선언하는 키워드, const는 상수를 선언하는 키워드다.
var, let 변수 선언 키워드는 리터럴 값의 재할당이 가능하지만, const는 리터럴 값의 재할당이 불가능하며 const 키워드는 선언과 동시에 리터럴 값을 할당해 줘야 한다. 여기서 말하는 리터럴은 let countNumber = 23; 에서 23이 리터럴이다. 

Scope

function-scoped 

 var 

 block-scoped

 let, const 


여기서 scope라는 말은 선언된 어떤 변수가 있다면 이 변수가 유효한 공간적 범위를 말한다. 자바스크립트에서는 크게 전역스코프와 함수스코프가 존재했었고, { ECMA6부터 블록스코프(중괄호스코프)를 지원한다. } => let, const

var(function-scoped)

var 변수는 스코프안에 가두려면, 반드시 함수가 필요하다. 그렇다면 스코프안에 가두기위한 방법을 아래 코드에서 확인해보자 

for ( var j = 0; j < 10; j++ ) {
 console.log('j', j)
}
console.log('after loop j is', j) // after loop j is 10 

for문이 끝난 다음 j를 호출하면 값 출력이 잘 된다.
이건 var가 hoisting(호이스팅) 되었기 때문이다.


hoisting(호이스팅) - 끌어올리다라는 뜻을 가지고 있음 

// 아래의 경우는 스코프안에 가두었기 때문에 에러가 발생한다

function counter() {

for(var i = 0; i < 10; i++){

console.log('i', i);

}

}

counter()

console.log('after loop i is', i); // ReferenceError: i is not defined


그렇다면 항상 function을 만들어서 호출해야 하는 것인가? 

다음은 immediately-invoked function expression ( or IIFE, pronounced 'iffy')

IIFE 로 function-scope 인 것 처럼 만드는 코드다.


(function(){

// var 변수는 여기까지 hoisting 

for ( var  i = 0; i < 10; i++ ){

console.log('i', i)

}

})()

console.log('after loop i is', i ) // ReferenceError : i is not defined


그렇다면 다시 아래 코드를 봐보자

(function(){

for ( i = 0; i < 10; i++ ){

console.log('i', i)

}

})()

console.log('after loop i is', i) // after loop i is 10 


위 코드는 에러없이 after loop i is 10이 호출된다. 왜 그럴까? IIFE를 사용해서 function-scope 처럼 보이게 해주었지만 결과는 다르다. 그 이유는 i 변수 값이 hoisting이 되어 global variable이 되었기 때문이다. 그래서 아래 코드처럼 된것이다.


var i

(function() {

for (  i = 0; i < 10; i++ ) {

.

.

.


IIFE 를 사용하는데 이렇게 hoisting이 된다면 function-scoped 에 의미가 없다. 

그래서 이런 hoisting을 막기 위해 use strict 을 사용한다.


(function() {

'use strict'

for ( i = 0; i < 10; i++ ) {

console.log('i', i);

}

})()

consoel.log('after loop i is', i) // ReferenceError : i is not defined


흠.. 그런데 변수 선언때문에 너무 많은 일을 하는 것 같다..

let 과 const 설명을 보자

let, const(block-scoped)

기존의 javascript 에서는 var 만 있었기 때문에 아래와 같은 문제가 있었다.


var a = 'test'

var a = 'test2'


이미 만들어진 변수이름으로 재선언 했는데 문제가 발생하지 않았고


c = 'test'

var c 


hoisting으로 인해 ReferenceError가 안났다.


하지만 let, const를 사용하면 var와 다르게 변수 재선언 불가능이다. 

둘의 차이점은 변수의 immutable 로 let 은 변수에 재할당이 가능하고, const 는 변수 재선언, 재할당이 모두 불가능하다. 

let

let a = 'test'
let a = 'test2' // 식별자 에러
a = 'test3'     // 가능

const

const b = 'test'
const b = 'test2' // 식별자 에러
b = 'test3'         // Uncaught TypeError:Assignment to constant variable.


let 과 const 가 hoisting이 발생하지 않는건 아니며 var function-scoped 로 hoisting이 되었다면

let 과 const 는 block-scoped 단위로 hoisting이 일어난다.


c = 'test' // ReferenceError: c is not defined

let c 


위의 코드에서 ReferenceError 가 발생한 이유는 temporal dead zone(tdz) 때문으로 let은 값을 할당하기전에 변수가 선언되어 있어야 한다. const 도 같지만 const 는 선언과 동시에 값을 할당 해야한다. 


const aa = 22;

const USER_NAME;  // 값을 할당하지 않을 시 에러 발생