Summary

Object.freeze() 메서드는 객체를 얼려 버립니다.  얼려 버린다는 것은 객체에 새로운 속성(property)를 추가할 수 없고, 객체에 원래 존재하던 속성을 제거할 수 없으며, 객체의 속성, 열거가능성(enumerability), 설정가능성(configurability), 값 쓰기 가능성(writability)을 변경할 수 없게 만든다는 것을 의미합니다. Object.freeze() 메서드는 결국 객체를 불변(immutable) 객체로 만들어 줍니다. Object.freeze() 메서드는 얼려진, 즉, 불변화 된 객체를 반환합니다.

 

Syntax

Object.freeze(obj)

Parameters

obj
얼릴(불변화 시킬) 객체.
 

Description

얼려진 객체에는 어떤 속성도 추가되거나 제거될 수 없습니다. 이런 시도는 암묵적이든, 아니면  strict mode에서와 같이 명시적으로 TypeError 예외를 던지든 모두 실패로 끝납니다.

데이터 속성에 의한 값은 변경될 수 없으며, getters와 setters 같은 접근자 속성에 의해서도 값은 변경될 수 없습니다(접근자 속성을 통해 값을 변경하면 오류가 발생하지 않으므로 값이 변경되었다고 생각할 수 있지만, 실제 값을 찍어보면 값은 변경되어 있지 않습니다). 하지만, 얼려진 객체의 속성값이 객체인 경우에는(즉, 값이 참조형일 경우에는) , 그 객체를 명시적으로 얼리지 않으면 그 객체는 변경될 수 있다는 점을 꼭 기억해야 합니다.

 

Examples

var obj = {
  prop: function() {},
  foo: 'bar'
};

// 새 속성을 추가할 수 있고, 기존 속성을 변경하거나 제거할 수 있음
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;

var o = Object.freeze(obj);

assert(Object.isFrozen(obj) === true);

// 얼린 후에는 모든 변경 시도가 실패로 끝남
obj.foo = 'quux'; // 에러가 나지는 않지만 값은 변경되지 않음
obj.quaxxor = 'the friendly duck'; // 에러가 나지는 않지만 속성이 추가되지 않음

// strict mode에서 위와 같이 변경을 시도하면 명시적으로 TypeError 발생
function fail(){
  'use strict';
  obj.foo = 'sparky'; // TypeError 발생
  delete obj.quaxxor; // TypeError 발생
  obj.sparky = 'arf'; // TypeError 발생
}

fail();

// 점(dot) 참조를 이용한 변경 뿐아니라 Object.defineProperty를 통한 변경 시도에서도 TypeError 예외 발생
Object.defineProperty(obj, 'ohai', { value: 17 }); // TypeError 발생
Object.defineProperty(obj, 'foo', { value: 'eit' }); // TypeError 발생

아래의 예제는 얼려진 객체 안에 있는 객체는 명시적으로 얼려지기 전까지는 변경가능하다는 것을 보여줍니다.

obj = {
  internal: {}
};

Object.freeze(obj);
obj.internal.a = 'aValue';

obj.internal.a // 'aValue' 가 출력됨

// obj 객체를 그 내부까지 완전히 얼리려면, obj 내의 모든 객체를 각각 얼려야 함
// 완전히 얼리려면 다음과 같은 함수를 이용할 수 있음

function deepFreeze(o) {
  var prop, propKey;
  Object.freeze(o); // 외부의 감싸는 객체 o부터 얼림
  for (propKey in o) {
    prop = o[propKey];
    if (!o.hasOwnProperty(propKey) || !(typeof prop === 'object') || Object.isFrozen(prop)) {
      // 내부 객체인 prop이 o에 있지 않고 프로토타입 객체에 있거나, prop의 타입이 object가 아니거나, prop이 이미 얼려있다면 얼리지 않고 통과
      // 이렇게 하면 이미 얼려진 prop 내부에 얼려지지 않은 객체 A가 있을 경우, A는 여전히 얼려지지 않는 상태로 남게됨
      continue;
    }

    deepFreeze(prop); // 재귀 호출
  }
}

obj2 = {
  internal: {}
};

deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // 새 속성인 a를 추가할 수 없으므로 undefined

 

Notes

ES5에서는 Object.freeze() 메서드의 인자가 객체가 아닐 때(즉, 원시형일 때)는 TypeError가 발생합니다. ES6에서는 원시형 인자도 얼려진 객체라고 취급해서 TypeError를 발생시키지 않고 원시형 인자를 그대로 반환합니다.

> Object.freeze(1)
TypeError: 1 is not an object // ES5 code

> Object.freeze(1)
1                             // ES6 code

Specifications

Specification Status Comment
ECMAScript 5.1 (ECMA-262)
The definition of 'Object.freeze' in that specification.
Standard Initial definition. Implemented in JavaScript 1.8.5.
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Object.freeze' in that specification.
Standard  

Browser compatibility

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
Basic support 4.0 (2) 6 9 12 5.1
Feature Firefox Mobile (Gecko) Android IE Mobile Opera Mobile Safari Mobile
Basic support ? ? ? ? ?

Based on Kangax's compat table.

See also

문서 태그 및 공헌자

이 페이지의 공헌자: roupkk, hanmomhanda
최종 변경: roupkk,