2016-08-18 4 views
4

だから私は、次のようなJavascriptのモジュールがあります。Javascriptでオブジェクトの配列をフリーズする良い方法はありますか?

const data = [ 
    { 
      id: 'do not modify', 
      name: 'do not modify' 
    },   
    { 
      id: 'do not modify 2', 
      name: 'do not modify 2' 
    } 
]; 

export default data; 

は、私は再帰的に明示的にそれぞれ、すべてのオブジェクトにObject.freeze()を呼び出すことなく、アレイ内のすべてのオブジェクトをフリーズすることができますきれいな方法はありますか?私は配列をループしてエクスポートする前にそれぞれをフリーズすることができたことに気がつきましたが、より洗練されたソリューションがあるかどうかを知りたいと思っていました。

+0

をあなただけの、それ自体がオブジェクト –

+4

'data.forEach(OBJ =>は、配列を、凍結することができますObject.freeze(obj)); '私にとっては複雑ではないようです。 – zzzzBov

+0

@zzzzBov:[Object.freeze() '](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)関数がわかったらそれは複雑ではありませんが、私はこれまでになかったことです(ありがとう!) –

答えて

5

あなたがしなければならないだろうすべてはArray.prototype.forEachObject.freezeを渡すことです:

'use strict'; 
 
var objs = [ 
 
    { a: 1 }, 
 
    { b: 2 }, 
 
    { c: 3 } 
 
]; 
 

 
objs.forEach(Object.freeze); 
 
objs[0].a = 4; // Fails due to being frozen

+0

私が危険にさらすことの1つは、ネイティブメソッドが時にはパラメータを追加するために変更され、 'forEach'が関数に3つのパラメータを提供するためです。それを包む。元の例では 'const'が使われていたので、これは' obj => Object.freeze(obj) 'を渡すのと同じくらい簡単です。 – zzzzBov

+0

@zzzzBovもちろん、 'Object.freeze'は1つのパラメータしか取らず、残りを無視します。しかし、特定の実装で問題が発生する場合は、無名関数を使用することは間違いありません。 –

+1

これは1つのパラメータをとり、残りのものは無視します*。誰かが2番目の 'deep'パラメータを追加するとどうなりますか?それは、あなたの使い方を壊す可能性のある後方互換性のある大幅な変更です。 – zzzzBov

-1

data.forEach(Object.freeze)は、あなたができる最善です。あなたのケースでは

ので、同じように、あなたはあなたのコードをクリーンアップすることができるかもしれません:

const data = [ 
    unmodifiableObj(0, 'Foo'), 
    unmodifiableObj(1, 'Bar') 
] 

export default data; 


function unmodifiableObj(id, name) { 
    return Object.freeze({ id, name }) 
} 
-1

MDN

からのサンプルコードを更新し、これを試してみてください:

凍結する
// To make obj fully immutable, freeze each object in obj. 
// To do so, we use this function. 
function deepFreeze(obj) { 

// Retrieve the property names defined on obj 
var propNames = Object.getOwnPropertyNames(obj); 

// Freeze properties before freezing self 
propNames.forEach(function(name) { 
var prop = obj[name]; 

// Freeze prop if it is an object 
if (typeof prop == 'object' && prop !== null) 
    deepFreeze(prop); 
}); 

// Freeze self (no-op if already frozen) 
return Object.freeze(obj); 
} 

を配列そのもの、およびそれに含まれる任意のオブジェクト

+3

'Object.freeze'は再帰的に動作しません。それは配列を固定しますが、配列内のオブジェクトは固定しません。 –

+0

["オブジェクトである値は固定されていない限り変更できます。"](https://developer.mozilla。org/ja-jp/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)。 – zzzzBov

+0

https://jsfiddle.net/mkj5z0rg/少なくとも配列のオブジェクトは 'Object.isFrozen()'に対してtrueを返します... –

0

すべてのオブジェクトでフリーズを呼び出すことなく、要素を内部に入れて配列をフリーズすることはできません。ここでは、私は上記のリンク先のページからコード貼り付けてるdeep凍結の例https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

を見つけることができます。

obj1 = { 
    internal: {} 
}; 

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

obj1.internal.a // 'aValue' 

// To make obj fully immutable, freeze each object in obj. 
// To do so, we use this function. 
function deepFreeze(obj) { 

    // Retrieve the property names defined on obj 
    var propNames = Object.getOwnPropertyNames(obj); 

    // Freeze properties before freezing self 
    propNames.forEach(function(name) { 
    var prop = obj[name]; 

    // Freeze prop if it is an object 
    if (typeof prop == 'object' && prop !== null) 
     deepFreeze(prop); 
    }); 

    // Freeze self (no-op if already frozen) 
    return Object.freeze(obj); 
} 

obj2 = { 
    internal: {} 
}; 

deepFreeze(obj2); 
obj2.internal.a = 'anotherValue'; 
obj2.internal.a; // undefined 
関連する問題