if (true) {
const i = 0;
}
//if block에서 지정한 변수 i는 참조 할 수 없다.
console.log(i);
두개의 변수 정의하기
let foo = 'bar1';
console.log(foo);
if(true) {
let foo = 'bar2';
console.log(foo); // ! 바깥에 있는 foo, 그리고 if 블록에 있는 foo둘 다 사용하지만, 가까운 변수를 사용하게 된다.
}
console.log(foo); // ! 블록안에 있는 변수는 참조 할 수 없기 때문에, 맨위에 지정되어진 변수를 참조하게 된다.
일반적으로 var에서 호이스팅을 확인해봤던 형식처럼 진행하게 되면 const와 let은 참조 에러를 발생시킨다.
console.log(foo); //에러발생
const foo = 1;
hosting이 안된다고 생각 할 수도 있지만, hosting이 가능하다. 아니, 위에서 이미 hoisting이 되었다. 다만, var에서는 undefined가 할당 되어졌다는 것과는 다르게 const, let은 아무것도 할당이 안되어진 상태이다. 아무값도 할당이 안되어진 상태에서 참조를 하고자하니 발생한 에러이다.
다음을 확인해보자.
const foo = 1;
{
console.log(foo);
const foo = 2; //hoisting이 되어지지만 역시나 값이 지정되어지지 않았기 때문에 error가 발생한다. ? 만약 해당 hoisting처리가 되어지는 변수를 주석처리 한다면, 당연히 1이 출력된다.
}
좀 더 익숙해지기 위해서 var변수로 해당형태를 다시보자.
var foo = 1;
(function () {
console.log(foo); // 함수 레벨에서 var 변수가 할당 되어진 것이 hosting되어, 출력시에는 undefined가 나오게 된다.
var foo = 2;
})();
하지만 let으로 지정된 함수는 재할당이 가능하다.
const bar = 'a';
bar = 'b';
var foo = 'a';
foo = 'b';
let value = 'a';
value = 'b';
다만, const로 정의되어진 내부 객체의 속성값은 수정이 가능하다.
const bar = { prop1: 'a'};
bar.prop1 = 'b';
bar.prop2 = 123;
console.log(bar);
const arr = [10,20];
arr[0] = 100;
arr.push(300);
console.log(arr);
//만약에 내부 속성값을 제어하고자 한다면 immer와 같은 외부 패키지를 사용해야한다.
//이러한 패키지는 기존 객체는 변경하지 않고, 새로운 객체를 생성한다.
만약 단순히 객체단위에서 수정을 막고자한다면, javascript 내장함수를 사용하면 된다.
'use strict';
const bar = Object.freeze({prop1 : 'a'});
bar.prop1 = 'b';
console.log(bar);
//이런 것들이 있다.
//Object.preventExtensions
//Object.seal
//Object.freeze