web-dev-qa-db-ja.com

JavaScriptで配列を「フリーズ」しますか?

ECMA-262仕様以降、JavascriptはObject.freeze()メソッドを取得しました。これにより、プロパティを変更、追加、または削除できないオブジェクトを使用できます。

var obj = {'a':1, 'b:2'};
Object.freeze(obj);
Object.isFrozen(obj);       // returns true
obj.a = 10;                 // new assignment has no affect
obj.a;                      // returns 1

ここまでは順調ですね。

私は、freeze()が配列でも機能するかどうか疑問に思っています。

var arr = [1, 2];
Object.freeze(arr);
Object.isFrozen(arr);      // returns true
arr[0] = 10;
arr;                       // returns [10, 2] ... ouch!

多分私は間違っているかもしれませんが、ArrayはObjectから継承するという印象を受けました。

typeof obj                 // "object"
typeof arr                 // "object"

任意のアイデア、ポインター、啓蒙は高く評価されます。

38
trembl

はい、フリーズは配列で機能するはずです。発生している動作は明らかに実装上のバグです。

このバグは、配列オブジェクトがカスタム [[DefineOwnProperty]] 内部メソッド(lengthプロパティを機能させる魔法)を実装しているという事実に関連している可能性があります。

2つの実装でテストしたところ、正しく動作しました(Chrome 16.0.888、Firefox Aurora 8.02a)。

2番目の質問については、配列オブジェクトはArray.prototypeから継承するObject.prototypeから継承します。たとえば、配列オブジェクトに対してObject.prototypeから非シャドウメソッドに直接アクセスできます。

['a'].hasOwnProperty('0'); // true

ただし、これはtypeofの動作には関係ありません。この演算子は、その種類に関係なく、オブジェクトのインスタンスの場合は'object'を返し、人々が常に持っているnullの値の場合は不満を言う。

typeof演算子の残りの可能な戻り値は、言語のプリミティブ型、Number、String、Boolean、Symbol、およびUndefinedに対応しています。

39
CMS

フリーズの代わりに、spreadオペレーターを使用して、変更せずにコピーします(もちろん、トランスパイラーを使用している場合)。

const second = {
  ...first,
  test: 20
}
0
neemiasjnr