2016-11-03 4 views
2

ECMAscriptのObject.freezeメソッドを理解しようとしています。Javascript Object.freeze()はオブジェクトの変更を防ぎません

私の理解は、オブジェクトのすべてのプロパティの変更を本質的に停止するということでした。 MDNドキュメントには、

が追加されています。既存のプロパティの削除を防ぎます。既存のプロパティ、またはその列挙可能性、構成可能性、または書き込み可能性が変更されることを防止します。

これは当てはまりませんが、恐らく私はドキュメントを誤解しています。ここで

は、その列挙プロパティで、私のオブジェクトであるexampleArray

function myObject() 
{ 
    this.exampleArray = []; 
} 

var obj = new myObject(); 
obj.exampleArray[0] = "foo"; 

私はオブジェクトを凍結する場合は今、私はそれにもはや任意の方法で変更することができるようexampleArrayプロパティは、あまりにも凍結しないことを期待します。

Object.freeze(obj); 
obj.exampleArray[1] = "bar"; 
console.log(obj.exampleArray.length); // logs 2 

"bar"が配列に追加されたため、フリーズされたオブジェクトが変更されました。私の即時の解決策は、目的のプロパティをフリーズすることだけです。

Object.freeze(obj.exampleArray); 
obj.exampleArray[2] = "boo"; 

ここで、アレイを変更するとエラーが発生します。

しかし、私は自分のアプリケーションを開発していますが、自分のオブジェクトに何が割り当てられるのかまだ分かりません。私のユースケースは、ゲームの開始時に(XMLファイルから)初期化されているいくつかのゲームオブジェクトがあることです。この後、私は誤ってプロパティを変更することはできないようにしたい。

おそらく私はフリーズメソッドを悪用していますか?オブジェクト全体をフリーズすることができますが、これは再帰的な凍結の一種です。私がここで考えることができる最良の解決策は、プロパティをループしてそれぞれをフリーズすることです。

私は既にこの質問を探していますが、唯一の答えは実装のバグだと言います。私はChromeの最新バージョンを使用しています。どんな助けもありがとうございます。

+0

このページの半分以下:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/Freezeこれは言う:**次の例は、フリーズされたオブジェクトは突然変異することがあります(フリーズは浅いです)。**設計通りに動作するようです。 –

答えて

4

Object.freezeは浅いフリーズです。

あなたはdocsに説明を見れば、それは言う:

値はデータプロパティのために変更することはできません。アクセサプロパティ(ゲッタとセッタ)は同じように機能します(値を変更しているという錯覚を引き続き与えます)。 オブジェクトでもある値は、凍結されていない限り変更することができます。

あなたは深い凍結対象にしたい場合は、ここでa good recursive example

function deepFreeze(o) { 
 
    Object.freeze(o); 
 

 
    Object.getOwnPropertyNames(o).forEach(function(prop) { 
 
    if (o.hasOwnProperty(prop) 
 
    && o[prop] !== null 
 
    && (typeof o[prop] === "object" || typeof o[prop] === "function") 
 
    && !Object.isFrozen(o[prop])) { 
 
     deepFreeze(o[prop]); 
 
     } 
 
    }); 
 

 
    return o; 
 
} 
 

 
function myObject() { 
 
    this.exampleArray = []; 
 
} 
 

 
var obj = deepFreeze(new myObject()); 
 
obj.exampleArray[0] = "foo"; 
 
console.log(obj); // exampleArray is unchanged

0

だそれはかなり奇妙だが、凍結は配列に要素を追加し、変異の要素を防止しています変異していない(奇妙なことに)...

たとえば、ES6では、変更されない変数を定義するときに "let"ではなく "const"で宣言します。あなたが言う場合:あなたはconstとして使用しているため

const foo = 'foo'; const foo = 'bar;

が、それはエラーがスローされます。あなたは

const foo = ['foo']; foo.append('bar');

を言うとき、それはエラーがスローされません。

0

writable:false,configurable:falseには、オブジェクトのプロパティ記述子をObject.defineProprtiesを使用して設定します。オブジェクトのObject.preventExtensionsを呼び出します。 How to create static array in javascriptを参照してください。

関連する問題