반응형

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로 초기화된 변수에 실제 값을 할당하는 단계

 

반응형

+ Recent posts