var 키워드
var 키워드는 ES6 이전에 변수를 선언하기 위한 유일한 방법이었습니다. var 키워드의 특징 중 하나는 변수 중복 선언이 가능하다는 것입니다. 아래 예시와 같이 중복해서 선언을 해도 에러가 발생하지 않습니다.
var x = 1;
var x = 'geumyong';
console.log(x); // geumyong
이렇게 중복선언이 가능하다는 것은 개발자가 실수로 이미 선언해놓은 변수에 다른 값을 재할당할 수도 있다는 위험이 있습니다.
두 번째 특징으로, 스코프 범위입니다. var 키워드는 함수 레벨 스코프를 갖습니다. 함수가 아닌 다른 블록 내에서(for문과 같은) var 키워드로 선언을 할 경우 전역 변수가 됩니다. 전역 변수의 경우 생명주기가 길고 어디서든 참조가 가능하기 때문에 피해주어야 됩니다.
세 번째 특징으로 변수 호이스팅이 일어납니다. 변수 호이스팅이란 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 특징을 말합니다. 아래 예시를 보면 이해가 될겁니다.
console.log(x); // undefined
var x;
변수 선언문이 log 실행보다 나중에 적혀있지만, 에러가 발생하지 않고 x 변수를 참조합니다. 이런 일이 가능한 이유는 변수 선언이 런타임 때 일어나는 것이 아니라 런타임 이전에 실행되기 때문에 가능한 일입니다. 런타임 이전에 선언 단계와 초기화 단계가 이루어지면서 undefined로 참조가 가능한 것입니다. 변수 호이스팅의 경우도 프로그램의 흐름상 맞지 않을 뿐더러 가독성도 안 좋아보입니다.
var 키워드로 선언할 경우, 이러한 문제점들을 안고 있기 때문에 ES6부터는 let, const 키워드를 사용하여 변수 선언을 합니다.
let 키워드
let 키워드로 선언한 변수의 경우 중복 선언이 안됩니다. 만약 중복 선언을 할 경우 문법 에러를 발생시킵니다. 그리고 블록 레벨 스코프를 갖기 때문에, var 키워드보다 좀 더 지역 스코프를 갖을 수 있는 범위가 넓어집니다. 마지막으로 변수 호이스팅이 발생하지 않는 것처럼 보입니다. var 키워드로 선언한 변수의 경우 런타임 이전에 선언 단계와 초기화 단계가 한 번에 진행이 됐지만, let 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행됩니다. 런타임 이전에 선언 단계가 먼저 실행되고 초기화 단계는 변수 선언문에 도달했을 때 실행됩니다. 선언 단계와 초기화 단계, 그 사이의 시간 공간을 일시적 사각지대(Temporal Dead Zone, TDZ)라 부릅니다.
그런데 위에서 호이스팅이 발생하지 않는 것처럼 보인다고 했습니다. 호이스팅이 발생하긴 합니다. 아래 예시를 보겠습니다.
let x = 1;
{
console.log(x);
let x = 2;
}
예시에서 console.log에는 어떠한 값이 찍히지 않고, 참조 에러가 발생합니다. 만약 호이스팅이 일어나지 않았다면 상위 스코프에 선언된 x 변수를 참조하여 1이 찍혔겠지만, 호이스팅이 일어나기 때문에 참조 에러가 발생하는 것입니다.
전역 객체
var 키워드로 선언한 전역 변수 혹은 전역 함수는 window의 프로퍼티가 됩니다. 예를 들어 전역 스코프에 var 키워드로 선언된 x 변수가 있다면, window.x로 접근이 가능합니다.
하지만 let 키워드로 선언된 전역 변수 혹은 전역 함수는 window의 프로퍼티가 되지 않습니다. 이는 렉시컬 환경에서 다른 레코드에 저장되기 때문입니다. 렉시컬 환경에 대해서는 추후 포스팅에서 실행 컨텍스트를 공부할 떄 같이 설명하겠습니다.
const 키워드
const 키워드는 let 키워드와 특징이 같습니다. 단지 const 키워드는 상수를 선언하기 위해 사용이 됩니다. 좀 더 명확히 말하자면 한 번 값을 할당하고, 그 값을 변경하고 싶지 않을 때 사용합니다. 고유 특징으로는 const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화를 해주어야 됩니다.
그리고 값을 변경하고 싶지 않을 때 사용한다라고 했는데, 이는 불변성을 갖는다는 의미는 아닙니다. 예로 객체를 const 키워드로 선언한 변수에 할당한다고 해서, 그 객체를 변경이 불가능하지 않습니다. 객체는 재할당없이도 직접 변경이 가능하기 때문입니다.(참조값에 의한 전달)
'JAVASCRIPT > 자바스크립트 이론' 카테고리의 다른 글
자바스크립트에서 this는 어떻게 바인딩될까 (5) | 2021.01.26 |
---|---|
프로토타입이란 (0) | 2021.01.26 |
스코프란 (3) | 2021.01.24 |
변수란 (0) | 2021.01.24 |
Falsy한 값 유형 (0) | 2020.06.16 |