30초 정리 - var vs let vs const
변수 선언 -> const
재할당 필요한 변수 선언 -> let
변수 선언 시 기본으로는 const 로 선언하고, 재할당이 필요하다면 그때 가서 let 으로 바꾸세요!
ES5까지 변수를 선언할 수 있는 유일한 방법은 var 였지만,
ES6 부터는 let, const 키워드로도 변수 선언이 가능해졌다.
우선 기존의 var 키워드가 어떤 문제가 있었는지 살펴보자.
변수 중복 선언 허용
var x = 1;
var y = 1;
var x = 100;
var y;
console.log(x); // 100
console.log(y); // 1
var 키워드로 선언한 x 변수와 y 변수는 중복 선언 되었으나 에러가 발생하지 않는다.
만약 내가 위에 apple 이라는 변수를 선언했는데, 그걸 까먹고 다시 apple 을 선언해 값을 바꿔버린다면
apple 을 이용한 코드에서는 무슨 일이 벌어질지 모른다.
함수 레벨 스코프
var 키워드로 선언한 변수는 오로지 함수의 코드블록만 지역 스코프로 인정한다.
아래 코드를 살펴보자.
var apple = '사과';
if (true) {
var apple = '배';
}
console.log(apple); // '배'
for 문에서 사용하는 i 도 마찬가지로 전역변수이다.
함수 레벨 스코프는 전역 변수를 남발할 가능성을 높인다.
변수 호이스팅
var 키워드로 변수를 선언하면 변수 호이스팅때문에 선언 이전에 undefined 로 초기화 될 수 있다.
console.log(a); // undefined
a = 123;
console.log(a); // 123
var a;
let
변수 중복 선언 금지
let 키워드로 이름이 같은 변수를 중복 선언하면 문법 에러가 발생한다.
let a = 123;
let a = 456; // error!
블록 레벨 스코프
let 키워드로 변수를 선언하면 모든 코드 블록을 지역 스코프로 인정하는 블록레벨 스코프를 따른다.
코드 블록은 함수, if 문, for 문, while 문, try/catch 문 등을 말한다.
let a = 123;
{
let a = 456;
let b = 123;
}
console.log(a); // 123
console.log(b); // ReferenceError
코드 블럭 내부에 있는 a 는 전역에 선언된 a 와는 다른 변수이다.
위 코드로 인해 let 은 블록 레벨 스코프라는 것을 알 수 있다.
변수 호이스팅
var 키워드로 선언한 변수와는 다르게 let 키워드로 변수를 선언하면
변수 호이스팅을 발생하지 않는 것처럼 동작한다.
console.log(a);
let a;
위 코드는 ReferenceError 를 뱉는다.
var 로 선언한 변수는 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언단계와 초기화 단계가 한번에 진행된다.
선언하고 곧바로 'undefined' 로 초기화 하는 것이다.
반면 let 키워드로 선언한 변수는 선언단계와 초기화 단계가 분리되어 진행된다.
런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언단계가 먼저 실행되나
초기화 단계는 변수 선언문에 도달했을 때 실행된다.
초기화가 되지않았는데 변수에 접근하게 되면 참조에러가 발생한다.
이처럼 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을
일시적 사각지대라고 한다.
console.log(a); // ReferenceError
let a; // 선언문에서 초기화 단계 실행
console.log(a); // undefined
a = 123;
console.log(a); // 123
let 키워드로 선언한 변수는 호이스팅이 발생하지 않는 것처럼 보이지만,
그렇지는 않다.
let a =123;
{
console.log(a); // ReferenceError !
let a = 456;
}
만약 호이스팅이 발생하지 않았다면 블록 내의 출력은 전역변수 a 의 값인 123 이여야한다.
하지만 호이스팅이 발생기에 참조에러가 발생하는걸 확인할 수 있다.
참고로 자바스크립트는 ES6에서 도입된
let, const 를 포함한 모든 선언(var, let, const, function, function*, class 등)을 호이스팅한다.
하지만 let, const, class 를 사용한 선언문은 호이스팅이 발생하지 않는 것 처럼 동작한다.
전역 객체 그리고 let
브라우저 환경에서 var 키워드로 선언한 전역 변수와 전역 함수 등은 전역객체 window 의 프로퍼티이다.
전역 객체의 프로퍼티를 참조할 때 window를 생략할 수 있어서 굳이 쓰지 않았던 것 뿐이다.
하지만 let 으로 선언한 전역변수는 전역 객체의 프로퍼티가 아닌
보이지 않는 개념적인 블록 내에 존재하게 된다.
const 키워드
상수(constant)를 선언하기 위해 사용하는 키워드이다. (물론 반드시 상수만을 위해 사용하지는 않는다)
const 의 특징은 let 과 거의 동일해서 책에서도 차이점 위주로 서술한다.
선언과 초기화
const 키워드를 이용하여 선언하는 변수는 무조건 선언과 초기화가 동시에 이루어져야한다.
const a = 1;
let과 마찬가지로 블록레벨 스코프를 가지고,
변수 호이스팅이 발생하지 않는 것 처럼 동작한다.
재할당 금지
const 키워드로 선언한 변수는 재할당이 금지된다.
상수
상수는 재할당이 금지된 변수를 말한다.
const 키워드로 선언된 변수에 원시 값을 할당한 경우 원시 값은 변경할 수 없는 값이고
const 키워드에 의해 재할당이 금지되어 할당된 값을 변경할 수 없다.
일반적으로 상수의 이름은 대문자로 선언해 상수임을 명확하게 나타낸다.
여러 단어는 언더스코어를 이용해 스네이크 케이스로 표현하는게 일반적이다.
const 키워드와 객체
const 키워드로 선언된 변수에 객체를 할당한 경우에는 값을 변경할 수 있다.
const box = {
color: 'red'
};
box.color = 'blue';
const 키워드는 재할당을 금지하는 것이지 "불변"을 의미하지는 않는다.
재할당은 불가능하지만 객체를 변경하는 것은 가능하다는 것이다.
'Archive > Develop' 카테고리의 다른 글
[ PostgreSQL ] CASE WHEN ~ END 와 비교연산(<>) (0) | 2022.09.21 |
---|---|
구조적 서브타이핑 / 잉여 속성 체크 (0) | 2022.09.21 |
[ 모던 자바스크립트 스터디 ] 전역변수의 문제점 (1) | 2022.09.20 |
[ Flask Migrate ] Multiple head revisions are present for given argument 'head' (0) | 2022.09.20 |
[ JavaScript ] Map & Reduce 요약 정리 (0) | 2022.09.19 |