let
과 const
는 ES2015부터 추가가 되었다.
var는 ES2015 이전에 사용되었던 변수 선언 방식이다. var
는 함수 스코프를 가지고 있어서 함수 내에서 선언된 변수는 함수 내에서만 접근이 가능하다. 하지만 let
과 const
는 블록 스코프를 가지고 있어서 블록 내에서 선언된 변수는 블록 내에서만 접근이 가능하다.
함수 스코프는 말 그대로 함수의 내부의 공간을 이야기 하며 블록 스코프는 {}
블록의 내부의 공간을 이야기 한다.
// var
if (true) {
var a = 10;
}
console.log(a) // 10 -> var는 함수 스코프이기 때문에 블록으로 인한 스코프 제한에 영향이 없다.
// let, const
if (true) {
let a = 10;
const b = 10;
}
console.log(a); // Uncaught ReferenceError: a is not defined
console.log(b); // Uncaught ReferenceError: b is not defined
또한 let
과 const
는 TDZ(Temporal Dead Zone)이라는 것이 있다. TDZ는 변수가 선언되기 전에 변수에 접근하려고 하면 에러가 발생하는 것을 이야기한다.
let은 선언 후 할당, 할당 후 재할당이 가능하다.
const는 선언과 할당이 동시에 일어나야 하며 재할당이 불가능하다.
전역공간이란? js환경에서 2가지로 나뉠 수 있다. 브라우저 환경에서는 window 객체를 의미하고 Node.js 환경에서는 global 객체를 의미한다.
만약 하나의 html에서 2개의 js파일을(1.js, 2.js) 사용하고 있다고 가정을 하였을 때 1.js에서 선언한 전역변수를 2.js에서 사용이 가능하다 즉 파일이 나뉘어 있다고 스코프가 분리되어 있지 않다는 것이다.
더 위험한 것은 만약 1.js에서 window 혹은 global의 프로퍼티를 조작을 하게 되면 이 후에 2.js에서는 조작된 프로퍼티를 사용하게 된다.
이 것들을 해결하기 위해 4가지의 방법이 있다.
그럼 결론적으로 전역 공간의 사용을 최소화 하는 방법은 아래와 같다.
임시 변수를 사용하게 되면 이 변수를 수정하고 싶은 유혹이 생긴다. 또한 명령형으로 가득한 로직이 되다 보니 코드에 대한 디버깅이 어려워 진다.
fuction test() {
const a = {};
a.name = 'leewoooo';
a.age = 27;
return a
}
// a라는 임시변수를 생성하는 것이 아닌 바로 return을 하는 방향으로
fuction test() {
return {
name: 'leewoooo',
age: 27
}
}
이를 해결하기 위한 방법은 아래와 같다.
호이스팅이란 변수에 대해 선언과 할당이 분리가 되어는 것을 이야기한다. -> 런타임 시 해당된다.
코드를 작성한 후 스코프를 예상하지만 런타임 시 호이스팅에 의해 var
, function
으로 선언된 변수 혹은 함수가 최상단으로 올라가게 된다. 그래서 함수를 선언할 때 추천하는 방법은 const
로 변수를 선언하고 해당 변수에 함수를 넣어주는 것이다. (함수 표현 식)
// 함수 표현식
const sum = function () {
return 1 + 2;
};
호이스팅의 문제점은 예측을 하기 어려우며 실행하기 전까지는 결과를 알 수 없다는 것이다. 그렇기 때문에 해결하는 방법은 아래와 같다.