동결과 밀봉의 차이점


164

방금 JavaScript 메소드 freeze및 에 대해 들었습니다 seal.

사용 방법에 대한 간단한 예는 다음과 같습니다.

var o1 = {}, o2 = {};
Object.freeze(o2);

o1["a"] = "worked";
o2["a"] = "worked";

alert(o1["a"]);   //prints "worked"
alert(o2["a"]);   //prints "undefined"

차이점은 무엇이며 freeze그리고 seal? 성능을 향상시킬 수 있습니까?


6
이 질문을보고있는 사람에게만 주면 받아 들인 대답은 실제로 틀립니다. @ tungd의 답변이 맞습니다.
Bjorn

2
또 다른 메모 Object.preventExtensionsObject.seal및에 Object.freeze있습니다. Object.preventExtensions새로운 아이템이 객체에 추가되는 것을 막습니다. 로 확장 성이 해제 된 객체의 속성 값을 삭제, 구성 및 변경할 수 있습니다 Object.preventExtensions.
Bjorn

답변:


193

Object.seal

  • 밀봉 된 물체로부터 특성을 추가 및 / 또는 제거하는 것을 방지한다; 를 사용 delete하면 false가 반환됩니다.
  • 기존의 모든 속성 을 구성 할 수 없습니다. '데이터 설명자'에서 '접근 자 설명자'로 (또는 그 반대로) 변환 할 수 없으며 접근 자 설명 자의 속성을 전혀 수정할 수 없습니다 (데이터 설명자가 writable속성을 변경할 수있는 경우) 해당되는 value경우 해당 속성 writeable).
  • TypeError봉인 된 객체 자체의 값을 수정하려고 할 때 (가장 일반적으로 엄격 모드에서 )를 던질 수 있습니다

Object.freeze

  • 정확히 무엇을 Object.seal하고 플러스 :
  • 기존 속성을 수정 하지 못합니다.

둘 다 '깊은'/ 손자 개체에는 영향을 미치지 않습니다. 예를 들어, obj고정 된 경우 obj.el재 할당 할 수 없지만 값을 obj.el수정할 obj.el.id수 있습니다 ( 예 : 변경 가능).


공연:

브라우저에 따라 개체를 봉인하거나 고정하면 열거 속도에 영향을 줄 수 있습니다.

  • Firefox : 열거 성능에 영향을 미치지 않습니다
  • IE : 열거 성능 영향은 무시할 수 있습니다.
  • Chrome : 봉인 또는 고정 된 개체로 열거 성능이 더 빠릅니다.
  • Safari : 봉인 또는 고정 된 개체가 92 % 느리게 열거 됨 (2014 년 기준)

테스트 : 밀폐 된 객체 , 고정 된 객체 .


2
왜 우리가 이러한 방법을 사용하는지에 대해 이야기 할 수 있습니까? 우리가 할 수 있다고 해서요?
Alan Dong

3
앞으로 도서관 / 프레임 워크를 개발할 때 그것들이 많이 사용될 것이라고 생각합니다. 이를 통해 사용자가 실수로 코드를 손상시키지 않도록 할 수 있습니다 (답변에 명시된 바와 같이 최적화는 속도가 크게 향상되어야합니다). 그러나 이것은 순수한 추측입니다 :)
Niccolò Campolungo

2
이 답변에는 많은 실제 오류가 있습니다. 하나 seal는 기존 속성을 구성 할 수 없게 만드는 것입니다. jsfiddle.net/btipling/6m743whn 번호 2를 참조하십시오. 여전히 편집 할 수 있습니다. 즉, 밀폐 된 객체의 기존 속성 값을 변경하는 것입니다.
Bjorn

8
FWIW, 고정 및 밀봉 된 물체는 이제 Chrome Canary v43.0.2317.0의 고정되지 않은 밀봉 된 물체보다 빠릅니다.
llambda

2
@AlanDong 조금 늦었지만 여기에 객체를 잠그는 이유가 있습니다. JavaScript의 기능 중 하나는 언제든지 속성을 추가 할 수 있다는 것입니다. 잘못 입력하여 실수 로이 작업을 수행 할 수도 있습니다 . 학생들의 대부분은 이벤트 핸들러라는 추가 시도 onClick또는 onlick그것이 작동하지 않는 이유를 궁금합니다. JavaScript에서 오류가 발생하면 잘못하는 것이 하나 더 적습니다. 둘째로, 변경을 방지하는 객체에 상수 속성을 구현할 수 있습니다. 이것은 객체 메조 드에 특히 유용합니다.
Manngo

119

이 세 가지 방법을 비교 하는 테스트 프로젝트 를 작성했습니다 .

  • Object.freeze()
  • Object.seal()
  • Object.preventExtensions()

내 단위 테스트는 CRUD 사례를 다룹니다.

  • [C] 새로운 속성 추가
  • [R] 기존 속성 읽기
  • [U] 기존 속성 수정
  • [D] 기존 속성 제거

결과:

여기에 이미지 설명을 입력하십시오


2
훌륭합니다. UPDATE는 디스크립터 속성 (예 : 구성 가능, 열거 가능, 쓰기 가능)을 수정 (defineProperty를 통해)하는 것을 고려합니까?
Drenai

나는 항상 DOM 객체를 밀봉해야합니다 (물론 폴리 필 후에). 많은 오타를 방지하는 데 도움이됩니다.
Manngo

@Manngo DOM 객체를 봉인 할 수 있습니다. 간단하게 만들 DEBUGMODE변수를하고로 설정합니다 true. 그런 다음을 수행하십시오 if (DEBUGMODE) { ... }. 에 ...모든 DOM 객체가 항상 봉인되도록하는 기능을 추가하십시오. 당신이 당신의 웹 페이지 스크립트, 변경, 배포 할 준비가되면 그런 다음 DEBUGMODE에를 false, 폐쇄 컴파일러를 통해 스크립트를 실행하고 배포 할 수 있습니다. 그렇게 간단합니다.
Jack Giffin

@JackGiffin 댓글 주셔서 감사합니다. 나는 항상 그것이 좋은 생각이라고 생각했다. 나는 element.onlick=something작동하지 않기 때문에 비슷한 것을 입력하고 좌절감을 느끼는 많은 학생들이 있지만 기술적으로 오류는 아닙니다.
Manngo

2
@Lonely 그러면 CRUD 철자가 아닙니다. RUDE;)에 만족해야합니다.
Manngo

84

당신은 항상 MDN에서 이것들을 찾을 수 있습니다. 한마디로 :

  • 고정 : 객체를 변경할 수 없게합니다. 즉 객체가 아닌 한 정의 된 속성을 변경할 수 없습니다.
  • 봉인 : 속성 추가를 방지하지만 정의 된 속성을 여전히 변경할 수 있습니다.

1
Object.seal()또한 프로토 타입 속성 을 고정 하는 것 같습니다 : \
K ..

10

Object.freeze()고정 된 개체를 만듭니다. 즉, 기존 개체를 가져 와서 기본적으로 개체를 호출 Object.seal()하지만 writable:false값을 변경할 수 없도록 모든 "데이터 접근 자"속성도로 표시합니다 . -Kyle Simpson, 당신은 JS를 모른다-이것 & 객체 프로토 타입


4

ECMAScript 5에서 Freeze와 Seal의 차이점을 살펴보고 차이점을 명확히하기위한 스크립트를 만들었습니다. 고정은 데이터 및 구조를 포함하여 변경 불가능한 객체를 만듭니다. Seal은 명명 된 인터페이스의 변경을 방지합니다 (추가, 삭제 없음). 그러나 객체를 변경하고 인터페이스의 의미를 재정의 할 수 있습니다.

function run()
{
    var myObject = function() 
    { 
        this.test = "testing"; 
    }

    //***************************SETUP****************************

    var frozenObj = new myObject();
    var sealedObj = new myObject();

    var allFrozen = Object.freeze(frozenObj);
    var allSealed = Object.seal(sealedObj);
    alert("frozenObj of myObject type now frozen - Property test= " + frozenObj.test);
    alert("sealedObj of myObject type now frozen - Property test= " + sealedObj.test);

    //***************************FROZEN****************************

    frozenObj.addedProperty = "added Property"; //ignores add
    alert("Frozen addedProperty= " + frozenObj.addedProperty);
    delete frozenObj.test; //ignores delete
    alert("Frozen so deleted property still exists= " + frozenObj.test);
    frozenObj.test = "Howdy"; //ignores update
    alert("Frozen ignores update to value= " + frozenObj.test);
    frozenObj.test = function() { return "function"; } //ignores
    alert("Frozen so ignores redefinition of value= " + frozenObj.test);

    alert("Is frozen " + Object.isFrozen(frozenObj));
    alert("Is sealed " + Object.isSealed(frozenObj));
    alert("Is extensible " + Object.isExtensible(frozenObj));

    alert("Cannot unfreeze");
    alert("result of freeze same as the original object: " + (frozenObj === allFrozen).toString());

    alert("Date.now = " + Date.now());

    //***************************SEALED****************************

    sealedObj.addedProperty = "added Property"; //ignores add
    alert("Sealed addedProperty= " + sealedObj.addedProperty);
    sealedObj.test = "Howdy"; //allows update
    alert("Sealed allows update to value unlike frozen= " + sealedObj.test);
    sealedObj.test = function() { return "function"; } //allows
    alert("Sealed allows redefinition of value unlike frozen= " + sealedObj.test);
    delete sealedObj.test; //ignores delete
    alert("Sealed so deleted property still exists= " + sealedObj.test);
    alert("Is frozen " + Object.isFrozen(sealedObj));
    alert("Is sealed " + Object.isSealed(sealedObj));
    alert("Is extensible " + Object.isExtensible(sealedObj));

    alert("Cannot unseal");
    alert("result of seal same as the original object: " + (sealedObj === allSealed).toString());

    alert("Date.now = " + Date.now());
}

3

조금 늦을 수도 있지만

  • 유사성 : 둘 다 확장 불가능한 객체 를 만드는 데 사용 됩니다 .
  • 차이점 : Freeze 구성 가능 에서 개체의 열거 가능하고 쓰기 가능 특성이로 설정되어 false있습니다. 봉인 된 쓰기 가능 속성에서로 설정 true되고 나머지 속성은 false입니다.

6
이것은 완전히 정확하지 않습니다. Object.getOwnPropertyDescriptor(Object.freeze({ prop: 1 }), 'prop').enumerable=== true.
레온 애들러

2

이제 전체 객체를 고정하는 대신 단일 객체 속성을 강제로 고정 할 수 있습니다. 당신이 이것을 달성 할 수 Object.definePropertywritable: false매개 변수로.

var obj = {
    "first": 1,
    "second": 2,
    "third": 3
};
Object.defineProperty(obj, "first", {
    writable: false,
    value: 99
});

이 예에서는 obj.first이제 값이 99로 잠겨 있습니다.


0

아래 기능을 비교하고 이러한 기능의 차이점을 설명하기 위해 간단한 테이블을 만들었습니다.

  • Object.freeze ()
  • Object.seal ()
  • Object.preventExtensions ()

위의 세 가지 방법의 차이점을 설명하는 표

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.