var는 javascript에서 es5 이전에 등장한 변수 선언 키워드 입니다.
let, const는 es6에서 등장한 변수 선언 키워드 입니다.
es6 이상에서는 대부분의 책, 블로그 들에서 var를 쓰지 말라고들 합니다.
그 이유에 대해서 알아볼게요
- 스코프
var는 함수 레벨 스코프를 가집니다.
let, const는 블록 레벨 스코프를 가집니다.
// var
var a = 1;
{
var a = 3;
console.log(a) // 3
}
console.log(a) // 3
// let
let b = 1 // 전역변수
{
let b = 2; // 지역변수
console.log(b) // 2
}
console.log(b) // 1
// const
const c = 1; // 전역변수
{
const c = 2; // 지역변수
console.log(c) // 2
}
console.log(c) // 1
let은 수정이 가능한 변수지만, const는 상수의 개념이기 때문에 수정이 불가능 해요.
둘 다 물론 중복 선언은 불가능합니다.(var는 가능해요)
- 호이스팅
호이스팅은 변수들의 선언을 코드 최상단으로 옮깁니다.
호이스팅 덕분에 이러한 것들이 가능합니다.
dogName("test")
function dogName(name) {
return "내 강아지 이름은 " + test + "입니다"
}
자바스크립트에서 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것이지요.
호이스팅에서는 var로 선언된 변수는 undefined로 변수를 초기화 시켜버리고 let,const로 선언된 변수는 초기화를 시키지 않아요.
함수 선언의 호이스팅이 되는 경우 문제가 발생할 수 있어요.
협업의 경우에서 생각해 볼게요
console.log(sum(1,2))
function sum(a, b) {
return a + b;
}
console.log(sum(2,3))
function sum(a, b) {
return "a + b = " + (a + b);
}
console.log(sum(3,4))
이전의 개발자는 sum을 결과값을 반환하게 했지만 이후의 개발자는 텍스트도 같이 반환하게 했습니다.
호이스팅으로 인해 이전의 코드에 영향이 갈수도 있어요.(매우 좋지 않네요)
함수 선언의 호이스팅을 방지하기 위해 함수 표현식을 사용하라고 권장하곤 합니다.
var sum = function (a, b) {
return a + b;
}
console.log(sum(2,3)) // 5
var sum = function (a, b) {
return "a + b = " + (a + b);
}
console.log(sum(3,4)) // a + b = 7
(이런.. 중복 선언또한 var는 가능하네요)
var, let, const는 모두 호이스팅이 되어집니다.
console.log(x) // undefined
var x = 1
var x;
console.log(x)
x = 1;
위의 함수는 에러를 발생시키지 않아요. 아래와 같이 변수 선언 들이 스코프 내에서 최상단으로 끌어올려져 버립니다.
이게 왜 문제가 될까요??
var i = 20
for (var i = 0; i < 10; i++) {
console.log(i)
}
console.log(i);
이와 같이 예전에 선언한 변수들에게 영향이 끼쳐 버리게 됩니다.
의도치 않게 변수값이 계속 바뀌어 버릴수 있어요
let과 const둘다 호이스팅이 되어 집니다. 하지만 이들은 호이스팅시 임시로 참조할수 없는 구역 TDZ(Temporal Dead Zone)에 위치하게 됩니다.
만약 호이스팅이 되지 않는다면
let foo = "foo"
{
console.log(foo); // 에러 발생
let foo = "bar";
}
// 호이스팅이 되지 않는다면 3번째 줄의 코드라인은 전역 객체의 foo를 참조해야만 합니다.
// 블록 스코프 내에서 foo가 호이스팅이 되고 TDZ에 존재하지 때문에 3번째 줄에서 에러가 나버려요
> TDZ: 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간 (일시적 사각지대)
* const는 변수의 선언과 할당을 동시에 해주어야만 합니다
let a;
a = 1;
// 아래 코드는 불가
const b; // error 발생
const b = 2
const c = 3;
* const는 상수의 개념이지만 mutable 객체의 경우 변경이 가능해요. 배열이나 객체와 같은 참조에 의한 전달이 이루어지는 경우 값의 변경이 가능해 집니다. => const 키워드는 재할당을 금지할뿐 '불변'은 아니다!!!
const building = {
floor: 4
}
building.floor = 5;
console.log(building)
> 자바스크립트는 es6에 도입된 모든 선언(var, let, const, function, function*, class)를 호이스팅 합니다. 단 es6에서 도입된 let, const, class를 사용한 선언문은 호스팅이 발생하지 않는 것처럼 동작합니다(TDZ개념 이용)
아래 3가지 권고사항만 잘 지킵시다
- es6를 사용한다면 var 키워드는 x
- 재할당이 필요한 경우에는 let키워드를 사용합시다! 이때 변수의 스코프는 최대한 작게 만들어 주도록
- 변경이 발생하지 않고 읽기 전용으로 사용하는 원시값과 객체에는 const 키워드를 사용합시다. const 키워드는 재할당을 금지하므로 var, let보다 안전합니다
변수 선언할때는 일단 const 쓰고 이후에 let으로 필요한 경우에 바꾸더라도 충분히 늦지 않아요!
출처 : https://developer.mozilla.org/ko/docs/Glossary/Hoisting
DeepDive 책
'Frontend > Javascript' 카테고리의 다른 글
innerHTML, insertAdjacentHTML, textContent, innerText (0) | 2022.03.01 |
---|---|
🔥Javascript questions (0) | 2022.02.28 |
🔥 System Design Concepts that Helped Me Get Sr Frontend Offers From Amazon & LinkedIn (번역글) (0) | 2022.02.27 |
js + cypress (0) | 2022.02.23 |
Frontend Interview Cheatsheet (0) | 2022.02.15 |