web-dev-qa-db-ja.com

フリーズとシールの違い

JavaScriptメソッドfreezeおよびsealについて聞いたばかりです。これらのメソッドは、Objectを不変にするために使用できます。

使用方法の簡単な例を次に示します。

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

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

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

freezesealの違いは何ですか?パフォーマンスを向上できますか?

143
maja

Object.seal

  • 封印されたオブジェクトのプロパティの追加や削除を防ぎます。 deleteを使用するとfalseが返されます
  • 既存のすべてのプロパティを作成します 設定不可 :「データ記述子」から「アクセッサ記述子」に変換することはできません(逆も同様です)。また、アクセサ記述子の属性をまったく変更できません(データ記述子はwritable属性を変更でき、valueがtrueの場合はwriteable属性を変更できます。
  • 封印されたオブジェクト自体の値を変更しようとすると、TypeErrorをスローできます(最も一般的にはstrictモード

Object.freeze

  • Object.sealが正確に行うこと、さらに:
  • any既存のプロパティの変更を防ぎます

どちらも「深い」/孫オブジェクトには影響しません。たとえば、objが凍結されている場合、obj.elは再割り当てできませんが、obj.elの値は変更できます。 obj.el.idは変更できます。


性能:

オブジェクトを封印または凍結すると、ブラウザによっては列挙速度に影響する場合があります。

  • Firefox:列挙のパフォーマンスは影響を受けません
  • IE:列挙のパフォーマンスへの影響はごくわずかです
  • Chrome:シールされたオブジェクトまたは凍結されたオブジェクトの場合、列挙のパフォーマンスが速くなります
  • Safari:封印または凍結されたオブジェクトの列挙が92%遅くなります(2014年現在)

テスト: シールされたオブジェクト凍結されたオブジェクト

176

私は テストプロジェクト を書いて、これらの3つの方法を比較しました:

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

私の単体テストはCRUDケースをカバーしています:

  • [C]新しいプロパティを追加
  • [R]存在するプロパティを読み取ります
  • [U]存在するプロパティを変更する
  • [D]存在するプロパティを削除

結果:

enter image description here

89
piecioshka

これらはいつでもMDNで調べることができます。要するに:

  • フリーズ :オブジェクトを不変にします。つまり、オブジェクトでない限り、定義済みプロパティの変更は許可されません。
  • シール :プロパティの追加を禁止しますが、定義されたプロパティは変更できます。
80
tungd

Object.freeze()はフリーズしたオブジェクトを作成します。つまり、既存のオブジェクトを取り、基本的にObject.seal()を呼び出しますが、すべての「データアクセサー」プロパティをwritable:falseとしてマークします。変更される-カイル・シンプソン、あなたはJSを知らない-これとオブジェクトのプロトタイプ

8
shmuli

ECMAScript 5のFreezeとSealの違いを見て、違いを明確にするスクリプトを作成しました。 Frozenは、データと構造を含む不変オブジェクトを作成します。 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
Jaycee

もう少し遅れるかもしれませんが、

  • 類似性:両方とも非拡張オブジェクトの作成に使用されます。
  • 違い:フリーズではconfigurable、enumerable、writableオブジェクトの属性はfalseに設定されます。 Sealed writableのように、属性はtrueに設定され、残りの属性はfalseです。
2
Faisal Naseer

オブジェクト全体をフリーズする代わりに、単一のオブジェクトプロパティを強制的にフリーズできるようになりました。これは、Object.definePropertyをパラメーターとしてwritable: falseを使用して実現できます。

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

この例では、obj.firstの値が99にロックされています。

0
jaggedsoft