참고
Syntax
Object.freeze(obj)
Parameters
obj
동결할 객체
Return value
함수로 전달된 객체(copy를 생성하는 것이 아님)
Basic
객체를 동결
동결된 객체는 아래 항목들이 모두 불가하다. * property 추가 또는 삭제 * value 변경 * 프로토타입이 변경
freeze()는 전달된 동일한 객체를 반환한다.
예시
const obj = {
prop: 42
};
Object.freeze(obj)
console.log(Object.freeze(obj));
// Object { prop: 42 }
obj.prop = 33;
// Throws an error in strict mode
console.log(obj.prop);
// Expected output: 42
Detail
동결 객체의 프로퍼티 set에는 추가/삭제가 불가능 해당 시도 시에는 실패하며 strict mode 일 경우 TypeError가 발생할 수 있음
writable과 configurable 속성도 false로 지정된다. getter, setter와 같은 Accessor property의 사용은 가능, 다만 setter를 사용하여도 에러가 발생하지 않지만 작동도 하지 않는다.
만약 동결한 객체의 value가 object 일 경우 수정이 가능하다 (shallow freeze)
예시
객체 동결
const obj = {
prop: function() {},
foo: 'bar'
};
// 동결 이전: 새 속성을 추가할 수 있고,
// 기존 속성을 변경하거나 제거할 수 있음
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;
// 동결
const o = Object.freeze(obj);
// 반환 값은 전달된 객체와 동일함.
o === obj; // true
// 객체가 동결 상태가 됨.
Object.isFrozen(obj); // === true
// 이제 모든 변경 시도는 실패함
obj.foo = 'quux'; // 조용하게 아무것도 하지 않음
// 조용하게 속성을 추가하지 않음
obj.quaxxor = 'the friendly duck';
// 엄격 모드에서는 이러한 시도에 대해 TypeError 발생
function fail(){
'use strict';
obj.foo = 'sparky'; // TypeError 발생
delete obj.foo; // TypeError 발생
delete obj.quaxxor; // 'quaxxor' 속성은 추가된 적이 없으므로 true 반환
obj.sparky = 'arf'; // TypeError 발생
}
fail();
// Object.defineProperty를 통한 변경 시도
// 아래 두 구문 모두에서 TypeError 발생
Object.defineProperty(obj, 'ohai', { value: 17 });
Object.defineProperty(obj, 'foo', { value: 'eit' });
// 프로토타입을 변경하는 것 또한 불가함
// 아래 두 구문 모두에서 TypeError 발생
Object.setPrototype(obj, { x: 20 });
obj.__proto__ = { x: 20 };
배열 동결
let a = [0];
Object.freeze(a); // 이제 배열을 수정할 수 없음.
a[0]=1; // 조용하게 실패
a.push(2); // 조용하게 실패
// 엄격 모드에서는 이런 시도에 대해 TypeError 발생
function fail() {
"use strict"
a[0] = 1;
a.push(2);
}
fail();
얕은 동결 (shallow freeze)
불변객체가 되기 위해서는 모든 reference graph가 불변의(immuatable) 동결 객체만 참조해야 한다.
var employee = {
name: "Mayank",
designation: "Developer",
address: {
street: "Rohini",
city: "Delhi"
}
};
Object.freeze(employee);
employee.name = "Dummy"; // non strict mode에서 조용하게 실패
employee.address.city = "Noida"; // 자식 객체의 속성은 수정 가능
console.log(employee.address.city) // 출력: "Noida"
깊은 동결
객체를 완전히 불변하게 만들기 위해서는 각각의 원시형이 아닌(non-primative) 프로퍼티를 재귀적으로 동결 시켜야 한다.
예시
function deepFreeze(object) {
// 객체에 정의된 속성명을 추출
var propNames = Object.getOwnPropertyNames(object);
// 스스로를 동결하기 전에 속성을 동결
for (let name of propNames) {
let value = object[name];
object[name] = value && typeof value === "object" ?
deepFreeze(value) : value;
}
return Object.freeze(object);
}
var obj2 = {
internal: {
a: null
}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue'; // 비엄격 모드에서 조용하게 실패
obj2.internal.a; // null
Object.seal()과의 비교
Object.seal()
를 사용해 봉인한 객체는 동결 객체와 마찬가지로 프로퍼티 set에 추가/삭제가 불가능
하지만 value는 변경할 수 있다.