https://medium.com/korbit-engineering/let과-const는-호이스팅-될까-72fcf2fac365
흔히들 var에서만 호이스팅이 일어난다고 생각하지만... 그렇지 않다!
let, const 변수는 그들의 어휘적 환경에 포함될 때 생성되지만, 어휘적 바인딩이 실행되기 전까지는 액세스할 수 없다. → 호이스팅이 일어나기는 하는 것 !! var 에서만 호이스팅이 일어나는 게 아니다 ~~
새로운 범위에 진입할 때마다 지정된 범위에 속한 모든 let/const바인딩이 지정된 범위 내부의 코드가 실행되기 전에 실행된다. (즉, let/const선언이 호이스팅된다.)
어휘적 바인딩이 실행되기 전까지 액세스할 수 없는 현상을 TDZ라고 한다.
→ 호이스팅이 일어나지만 TDZ에 의해 오류가 발생되는 것 ~~
// const x를 실행하기 전에 x에 접근하면, TDZ에 의해 ReferenceError가
발생하게 된다.
// console.log(x);
const x = 42;
// 위 코드 실행 이후에는 x에 접근할 수 있다.
console.log(x);
속성 변경만 가능. 왜? const로 선언한 변수와 객체 사이의 바인딩은 변경되지 않기 때문!
const는 사실 더 이상 말할 것이 없을 정도로 let과 유사하다.
다만 상수 선언 키워드로 사용되기 때문에 값을 재 할당하는 것이 불가능하고, 선언과 할당이 동시에 이루어져야 한다.
// const 키워드는 재 할당을 할 수 없다.
const name = "Yorr";
name = "John"; // Uncaught TypeError: Assignment to constant variable.
// const 키워드는 선언과 할당이 동시에 이루어져야 하기 때문에 선언만 할 수 없다.
const name; // Uncaught SyntaxError: Missing initializer in const declaration
하지만 객체(Object)에 대해서는 식별자나 프로퍼티명을 통해 직접 접근해서 값을 변경할 수 있다.
const obj = {
name: "Yorr"
};
obj.name = "John";
console.log(obj); // John
위의 설명을 통해 객체에 대해 식별자나 프로퍼티명을 통해 값을 변경할 수 있다면 굳이 let과 같은 변수 선언이 아닌 상수 타입을 사용해야 하냐는 생각을 할 수 있다.
다음 코드를 확인해보자.
const obj = {};
obj = function () {}; // Uncaught TypeError: Assignment to constant variable.
위 코드에서 obj라는 객체가 이미 const로 선언이 되었기 때문에 식별자에 새 리터럴 값을 할당하는 것이 불가능하다.
그렇기 때문에 다음과 같은 코드도 불가능하다.
const obj = {
name: "Yorr"
};
obj = "John"; // Uncaught TypeError: Assignment to constant variable.
즉, 값을 const로 선언해서 사용하는 이유는 값이 가진 타입의 변경을 제한하겠다는 것이다.
실제로 Node.js나 Vue.js와 같은 Javascript 기반의 언어나 프레임워크를 사용하다 보면 대부분의 값을 const로 선언해서 사용하는 것을 볼 수 있다.
그 이유는 사실 값을 변경하는 변수를 사용할 일이 생각보다 많지 않고, const를 통해 선언한 값의 타입을 유지하는 것이 개발에 있어 많은 실수를 방지해주기 때문이다. (특히 Javscript 이기 때문에 더 그렇다. 그래서 TypeScript가 굉장히 많은 사랑을 받고 있는 것 같다.)
let + freeze vs const + freeze vs constconst 객체의 경우 속성 변경이 가능. 따라서 완전히 immutable한 상수라고 보기 어려움
freeze:
let + freeze :
let itGo = {
elsa = 'Princess';
};
// freeze. 객체 동결!
Object.freeze(itGo);
// itGo.elsa = 'frog' X 객체 변경 불가능!
// 그러나... let이어서 재할당이 허용된다.
itGo = {
else = 'frog'
};
// 실패!
const + freeze :