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"
任意のアイデア、ポインター、啓蒙は高く評価されます。
はい、フリーズは配列で機能するはずです。発生している動作は明らかに実装上のバグです。
このバグは、配列オブジェクトがカスタム [[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に対応しています。
フリーズの代わりに、spreadオペレーターを使用して、変更せずにコピーします(もちろん、トランスパイラーを使用している場合)。
const second = {
...first,
test: 20
}