[JS] 15. let, const

heyhey·2023년 7월 18일
0
post-thumbnail

15.1 var로 선언한 변수의 문제점

ES5까지는 var밖에 변수를 선언할 수 있는 방법이 없었다.
하지만 var는 여러 문제를 발생 시킬 수 있다.

  • 메모리 누수
  • 디버깅 어렵다.
  • 가독성 떨어진다.

변수 중복 선언 허용

var는 중복 선언이 가능하다. 그래서 이미 선언되어 있는 값을 의도치 않게 변경해버릴 수 있기 때문에 부작용이 발생할 수 있다.
값을 할당한지 않은 선언이라면 무시되며 동작되는 점만 알아두자

함수 레벨 스코프

var는 오로지 함수의 코드 블록만을 지역 스코프로 인정한다.
즉 함수 밖의 변수는 모두 전역 변수가 되어버린다.

var x = -1;
// 함수가 아니다.
if (true) {
  var x = 10;
}
x; // 10
var i = 10;
// 이것도 함수가 아니다
for (var i = 0; i < 5; i++) {
  console.log(i);
}
i; // 5

이렇듯 함수 레벨 스코프는 전역 변수를 남발할 가능성을 높여 변수가 중복 선언되어 버릴 수가 있다.

변수 호이스팅

js의 호이스팅 때문에 오류를 발생시키고 가독성을 떨어뜨릴 수 있다.

foo? // undefined
foo = 123;
foo? // 123
var foo;

호이스팅 때문에 변수를 선언하기 전에 값을 할당을 해도 값이 할당되어 버린다.

let

var의 단점을 해결하기 위해 let 과 const가 도입되었다.

변수 중복 선언 금지

중복되는 변수명을 사용하면, 문법에러(syntex) 가 발생한다.

블록레벨 스코프

블록레벨 스코프는 중괄호{} 안의 내용으로 이해하면 된다.

let foo = 1;
{
  let foo = 2;
  let foo2 = 4
}
foo // 1
foo2 ? // 에러

if나 for 에서의 괄호도 블록레벨이기 때문에, 위의 var에서의 문제점이 해결된다.

호이스팅

let은 호이스팅이 발생하지 않는 것처럼 동작한다.
선언 단계는 먼저 실행되지만, 초기화가 변수 선언문에 도달되었을 때 실행되기 때문이다.

var는 선언단계초기화 단계가 한번에 진행된다.
let은 선언단계초기화 단계가 분리되어 진행된다.

스코프의 시작부터 변수를 초기화 해주는 단계 까지 변수를 참조할 수 없는 구간을 일시적 사각지대 라고 부른다.

그렇다면 호이스팅이 발생하지 않는다고 이해해도 되지 않나?
그건 아니다. 예시를 통해 보자

let foo = 1;
{
  console.log(foo); // 참조 에러
  let foo = 3;
}

foo가 존재하기 때문에 스코프가 시작할 때 참조할 수 있어야 한다.

하지만 블록레벨에서 foo를 선언했고, 그 값을 참조하려고 하기 때문에 에러가 발생한다.
동작만 호이스팅이 발생하지 않는 것처럼 보이지, 실제로는 모든 선언을 호이스팅한다.

전역 객체와 전역 변수

var로 선언한 전역 변수는 전역 객체 (window)의 프로퍼티이다.
이 전역 변수는 window를 생략해도 사용가능하다.

var x = 1;
y = 2;
console.log(window.x); //1
console.log(x); //1
console.log(window.y); //2
console.log(y); // 2

하지만 let으로 선언한 변수는 전역 객체의 프로퍼티가 아니기 때문에, window.x 와 같이 접근할 수 없다.
let은 전역 렉시컬 환경의 선언적 환경 레코드에 존재한다.

let x = 1;
console.log(window.x); // err
console.log(x); // 1

15.3 const

const 는 상수를 선언하기 위해 사용한다.

선언과 초기화

const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 한다.

let a;
const b; // err

재할당 금지

let은 변수 재할당이 자유로우나, const는 재할당이 금지되어 있다.

상수

상수는 재할당이 금지된 변수이다.

const로 변수원시값을 할당하면 변경할 수 없다.
원시값은 변경 불가능하기 때문에 재할당 없이 값을 변경할 수 없다.

만일 객체를 할당한 경우에는 값을 변경할 수 있다.
재할당 없이도 직접 변경이 가능하기 때문이다.

결국 const는 재할당을 금지할 뿐, 불변을 의미하진 않는다.

const a = {name:'aa'}
a.name = 'bb'
a ? // {name:'bb'}

| const로 선언한 변수가 객체면 변경 가능하다.
| 객체는 변경되더라도 변수의 참조값은 변경되지 않기 때문이다.

15.4 const vs let

var는 사용하지 않아야한다.
변수 선언에는 기본적으로 const를 사용하며, let은 재할당이 필요한 경우에 사용하는 것이 좋다.

일단 const로 만드록 필요 시점에 let으로 변경해서 써도 되니깐..

profile
주경야독

2개의 댓글

comment-user-thumbnail
2023년 7월 18일

정말 좋은 정보 감사합니다!

답글 달기
comment-user-thumbnail
2023년 7월 18일

글 잘 봤습니다, 많은 도움이 되었습니다.

답글 달기