2

オブジェクトの読み取り専用プロパティと適切な単体テストを作成しました。

//works as expected
function OnSelf() {
    this._val = 'test';
    Object.defineProperty(this, 'test', {
        enumerable: true,
        configurable: false,
        get: function () {
            return this._val;
        }
    });
} 

しかし、個々のインスタンスではなく、プロトタイプに読み取り専用プロパティを配置する必要があることに気付きました。コードを変更したら、テストの 1 つが失敗しました。

//no exception when trying to delete the property
function OnPrototype() {
    this._val = 'test';

}
Object.defineProperty(OnPrototype.prototype, 'test', {
    enumerable: true,
    configurable: false,
    get: function () {
        return this._val;
    }
});

プロトタイプの読み取り専用プロパティを削除しても例外はスローされませんが、プロパティがオブジェクトにある場合は例外がスローされるようです。

var s = new OnSelf();
delete s.test; // throws error

var p = new OnPrototype();
delete p.test; // doesn't delete it, but no error occurs

問題を示すためにhttp://jsfiddle.net/pdgreen/3BGfM/を作成しました。chrome と firefox の Mac でも同様の動作を確認しました。

これは正しいことですか?プロパティがオブジェクトにある場合、例外がスローされますが、プロトタイプでは例外がスローされないのはなぜですか? これは私を驚かせます。なぜそうなのか、誰か説明できますか?

4

2 に答える 2

4

それはあなたが見ている正しい動作です。「delete」キーワードは、オブジェクト自体のプロパティのみを削除します。オブジェクトのプロトタイプのプロパティを削除することはできません。(もしそうなら、それはひどいことです -- 同じプロトタイプから継承している他のオブジェクトを台無しにしてしまいます!)

次のことを試してください。

> function Constructor() {}
undefined
> Constructor.prototype.test = "Prototype";
"Prototype"
> var obj = new Constructor();
undefined
> obj.test
"Prototype"
> obj.test = "Child"
"Child"
> obj.test
"Child"
> delete obj.test
true
> obj.test
"Prototype"

プロトタイプ継承の鍵は、プロトタイプが独自のプロパティを含む実際のオブジェクトであり、継承が完全にライブで動的であることです。オブジェクトがプロパティを定義していないが、そのプロトタイプ チェーン内のオブジェクトが定義している場合、子オブジェクトはその値を継承します。その値がローカルでオーバーライドされると、そのプロパティ自体が定義されるようになりました。子オブジェクトのプロパティが削除されると、プロトタイプからの値が再び取得されます。

于 2013-01-24T07:34:47.993 に答える
1

プロパティがオブジェクトで直接定義されている場合、オブジェクトには削除可能な「独自の」プロパティがあります。ただし、プロパティがプロトタイプで定義されている場合、削除する「独自の」プロパティがないため、削除操作はノーオペレーションです。プロパティは実際にはプロトタイプにあります (これがプロトタイプの継承のしくみです。変更されない限り、プロパティは実際にはオブジェクトに追加されません)。

これを理解することは、通路のねじれた迷路であり、すべて同様です... ES5 仕様としても知られていますが、重要なセクション (それへの道をデコードした後) は8.12.7GetOwnPropertyであり、そのセクションで説明されている内部メソッドを認識することと相まってundefinedプロトタイプの場合に戻ります。

于 2013-01-24T07:33:33.093 に答える