回答(以下をお読みください。それぞれの著者が貴重な洞察を提供してくれました):
- 「writable: false」は新しい値の割り当てを防ぎますが、 Object.defineProperty は割り当て操作ではないため、「writable」の値を無視します
- プロパティ属性は継承されるため、1 つのサブクラス (またはサブクラスのインスタンス) が「書き込み可能」の値をそれ自体の true に戻すまで、プロパティはすべてのサブクラス/インスタンスで書き込み不可のままになります。
質問:
プロパティ「書き込み可能」記述子に関する MDN ドキュメントには、次のように記載されています。
書き込み可能 プロパティに関連付けられた値が代入演算子で変更できる場合にのみ true。デフォルトは false です。
公式の ECMA-262 第 6 版は多かれ少なかれ同じことを述べています。意味は明らかですが、私の理解では、元のプロパティ (つまり、その特定のオブジェクトのプロパティ) に限定されていました。
ただし、次の例 ( JSFiddle )を考慮してください。
//works as expected, overloading complete
var Parent = function() {};
Object.defineProperty(Parent.prototype, "answer", {
value: function() { return 42; }
});
var Child = function() {};
Child.prototype = Object.create(Parent.prototype, {
answer: {
value: function() { return 0; }
}
});
var test1 = new Parent();
console.log(test1.answer()); //42
var test2 = new Child();
console.log(test2.answer()); //0
//does not work as expected
var Parent2 = function() {};
Object.defineProperty(Parent2.prototype, "answer", {
value: function() { return 42; }
});
var Child2 = function() {};
Child2.prototype = Object.create(Parent2.prototype);
test3 = new Parent2();
console.log(test3.answer()); //42
test4 = new Child2();
test4.answer = function() { return 0; };
console.log(test4.answer()); //42
この例に従うと、プロパティは書き込み可能ではありませんが、予想どおり、サブクラス (test2) のプロトタイプでオーバーロードできることがわかります。
ただし、サブクラスのインスタンス (test4) でメソッドをオーバーロードしようとすると、暗黙のうちに失敗します。test2 と同じように動作することを期待していました。親のインスタンスでプロパティをオーバーロードしようとすると、同じことが起こります。
同じことが NodeJS と JSFiddle の両方で発生し、特定の条件下では、インスタンスでオーバーロードすると、プロパティの読み取り専用の性質に関する TypeError がスローされます。
これが予期された動作であることを確認していただけますか? もしそうなら、説明は何ですか?