JavaScript 변수
데이터를 처리하기 위해서는 데이터가 어떤 값인지를 저장해놓고 불러와 사용하는 과정이 필수적이다.
그리고 컴퓨터는 데이터를 저장하기 위해 기억장치인 메모리를 활용한다.
메모리에 데이터를 담아 기억을 해두고, 메모리의 각 장소마다 존재하는 주소값을 통해 기억해둔 데이터를 찾는다.
그리고 이 주소값을 대신할 식별자를 지정하고 식별자를 통해 데이터에 접근하는데 그 식별자가 변수이다.
즉, 변수란 데이터를 저장해둔 메모리 주소를 쉽게 식별하기 위해 붙인 이름이다.
var, const, let
JavaScript는 코드 평가 단계, 코드 실행 단계동안 다음과 같은 과정을 통해 변수를 생성한다.
선언 단계: 변수를 변수 객체에 등록한다.
초기화 단계: 변수를 메모리에 할당하고 undefined(값이 없음) 상태로 초기화한다.
할당 단계: undefined로 초기화된 변수에 실제로 값을 할당한다.
그런데, 이 3단계는 변수를 선언하는 var, const, let마다 다르게 동작한다.
- var
var는 코드 평가에서 선언 단계, 초기화 단계를 거치고 코드 실행에서 할당 단계를 거친다.
console.log(a);
console.log(b);
var a;
var b = 2;
// output
// undefined
// undefined
따라서 다음과 같은 코드가 있을 때, 에러가 발생하지 않고 undefined가 출력된다.
코드 평가 단계에서 미리 a와 b를 undefined로 할당하였고 코드 실행 단계에서 a와 b는 undefined 상태이기 때문이다.
이와 같이 모든 선언문이 해당 스코프의 선두로 옮겨진 것처럼 동작하는 특성을 호이스팅이라 한다.
또한 var은 전역 변수화되어 어디서든 접근이 가능하다.
이는 장점이 될 수도 있겠지만, 의도치 않은 변수값이 변경될 수 있고 코드 예측이 어려워지는 단점도 존재한다.
- const, let
const와 let은 코드 평가에서 선언단계, 코드 실행에서 초기화 단계와 할당 단계를 거친다.
console.log(a);
console.log(b);
let a = 1;
const b = 2;
// error
// ReferenceError: Cannot access 'a' before initialization
따라서 코드 평가에서는 선언만 되었을 뿐 undefined로 초기화되지 않았으므로 실행 단계에서 에러가 발생한다.
또한 const와 let은 var과 다른 블록 레벨 스코프로 한정적으로 접근이 가능하여 예측 가능한 범위 내에서 변수 변경이 일어난다.
const는 "상수"를 선언할 때 사용되며 한 번 값을 할당하였으면 수정이 불가능한 특징을 가지고 있다.
또한 무조건 값을 할당해야만 하고 할당하지 않은 경우에는 에러가 발생한다.
const a;
// SyntaxError: Missing initializer in const declaration
const b = 1;
b = 3;
// TypeError: Assignment to constant variable
let은 var과 마찬가지로 한 번 값을 할당하더라도 다른 값으로 재할당이 가능하다.
또한 값을 할당하지 않아도 생성이 가능하다.
let a;
console.log(a); // undefined
a = 1;
a = 2;
console.log(a); // 2
const a = 1;
let b = 2;
var c = 3;
for (let i = 0; i < 1; i++) {
const a = 4;
let b = 5;
var c = 6;
console.log(a);
console.log(b);
console.log(c);
}
console.log(a);
console.log(b);
console.log(c);
// output
// 4
// 5
// 6
// 1
// 2
// 6