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에서 나온 변수 선언 방식이 let과 const 이다.
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로 초기화된 변수에 실제 값을 할당하는 단계
'JavaScript' 카테고리의 다른 글
[JavaScript] 숫자 3자리마다 콤마찍기(정규식) (1) | 2021.02.15 |
---|---|
[javascript] 클릭시 마우스 효과 나타내기 (0) | 2020.02.08 |
[javascript] 배열 문자열 검색 (0) | 2020.02.01 |
[Javascript] 매개변수 전달인자에 따른 바인딩 (0) | 2018.04.30 |
[Javascript] 함수의 매개변수(arguments 객체) (0) | 2018.04.27 |