본문 바로가기
JavaScript

[javascript] var, let, const 차이점

by 휘두루미 2020. 2. 5.
반응형

ES5에서는 변수를 표현할 방법이 var 밖에 없었다.

var로 표현된 변수는 편리한만큼 제대로 쓰지 않으면 위험요소가 너무 많았다.

 

var 변수의 특징

1. 함수레벨 스코프

- 전역함수 외부에서 생성된 변수는 모두 전역변수의 취급을 받는다. 따라서 전역변수를 남발하게 될 가능성이 높다.

 

2. 변수 중복 선언 허용

var test = 'javascript';
console.log(test); // javascript

var test = 'typescript';
console.log(typescript); // typescript

test 라는 변수를 한번 더 선언했음에도, 그대로 test 변수에 담긴 값이 console.log의 위치에 따라 다르게 출력된다.

이는 '변수 - 여러가지 값으로 변할 수 있는 수' 라는 개념에는 맞을 수 있으나,

코드량이 많아지고 무분별하게 사용된다면 하나의 변수값으로 어디에서 사용되고 변화하는지 예측하기 힘들다.

 

코드의 수정이 있을때 역으로 한참을 올라가야 할 지도 모를 경우가 생길 수 있다.

 

이 외에도 여러가지 단점을 보완하기 위해 ES6에서 나온 변수 선언 방식이 letconst 이다.

 

let 변수의 특징

1. 블록레벨 스코프

- 코드블록(function, if, for, while, try/catch 등) 내에서 선언된 변수는 해당 블록 내에서만 유효하며, 선언된 변수는 지역변수이다.

 

2. 변수 중복 선언 불가

let test = 'javascript';
{
  let test2 = 'jquery';
}
let test = 'typescript';

console.log(test); // Uncaught SyntaxError: Identifier 'test' has already been declared
console.log(test2); // pen.js:24 Uncaught ReferenceError: test2 is not defined

console.log(test) - 이미 코드 최상위에 test라는 let 변수의 값으로 'javascript' 라는 값을 넣었고,

다시 test 변수에 'typescript' 라는 값으로 바꾸려니 이미 선언되었다는 에러를 뱉어낸다.

test2의 경우 let변수는 블록레벨 스코프이자 지역변수 이기 때문에, { } 범위를 벗어나서 console 을 찍게되면

선언되지 않았다는 에러를 뱉어내게 된다.

 

값을 바꾸고 싶다면, let test = 'typescript' 가 아닌 test = 'typescript' 로 해야한다.

let을 선언하는 순간 새로운 변수를 선언하는거와 같은 의미로 판단해, 이미 test라는 let변수가 존재한다고 하는 것이다.

let test = 'javascript';

test = 'typescript';

console.log(test); // typescript

 

const 의 특징

const는 상수값(변하지 않는 값)을 위해 사용된다. 기본적인 특징은 let과 동일하다.

다른점은 다음과 같다.

 

1. 재할당이 되지 않는다.

const test = 'javascript';

test = 'typescript';

console.log(test); //Uncaught TypeError: Assignment to constant variable.

2. 값이 무조건 바뀌지 않는 것이 아니다.

- 재할당이 불가능하다는 것은 const 변수 타입이 '객체' 인 경우, 참조값을 변경하지 못한다는 것을 의미한다.

- 하지만, 객체의 프로퍼티는 보호되지 않는다. 이는 할당된 객체의 내용(property의 추가, 삭제, 변경)은 변경이 가능하다는 것을 의미한다.

const user = {name: 'HwiDoorumi'};

// 1. user 객체의 참조값을 변경하려는 경우 
// user = {} //Uncaught TypeError: Assignment to constant variable.

user.name = 'Hwi';
console.log(user); // {name: 'Hwi'}

const로 선언된 user 객체는 name 이라는 key로 'HwiDoorumi' 라는 value 를 가진다.

따라서 user객체는 {name: 'HwiDoorumi'} 라는 참조값을 가지고 있으므로,

user = {} 라고 참조값을 변경하려고 했을때 에러를 뱉어내지만

name이라는 key를 가지는 property value인 'HwiDoorumi' 를 변경하는것은 가능하다는 것을 의미한다.

 

3. const 객체는 반드시 선언과 동시에 할당이 이루어져야 한다.

const test;

test = 'HwiDoorumi';

console.log(test); // Uncaught SyntaxError: Missing initializer in const declaration

var나 let의 경우, 위의 코드에서 에러를 뱉어내지 않는다.

하지만 const의 경우 위 코드를 해석하면

 

1. const 타입의 test 객체를 선언

2. test 객체를 'HwiDoorumi' 라는 값으로 변경 // 변수의 재할당 시도, 에러발생

 

const 객체의 특징에서 재할당이 불가능하다는 것에 위반된다. 따라서 const객체는 반드시 선언, 할당이 동시에 이루어져야 한다.

 

 

[참고] 변수의 선언, 초기화, 할당

[선언단계] - Declaration phase
변수를 실행 컨텍스트의 변수객체(Variable Object)에 등록한다.
이 변수 객체는 스코프가 참조하는 대상이 된다.

'variable Object' is not defined 라는 에러를 뱉어낸다면, 선언이 되지 않은 것을 의미한다.
[초기화 단계] - Initialization phase
변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다.
이 단계에서 변수는 undefined로 초기화 된다.

에러문구에서 'variable Object' is not defined 라는 에러를 뱉어낸다면
선언자체가 되지 않았다는 것이고, undefined 라는 에러를 뱉어낸다면
선언과 초기화는 되었지만, 값이 할당되지 않았다는 것을 의미한다.
[할당단계] - Assignment phase
undefiedn로 초기화된 변수에 실제 값을 할당하는 단계

 

반응형