1

文字列/関数/その他のオブジェクトがインスタンス化されると、__proto__プロパティが含まれます。このプロパティは、 ...の__proto__アクセサーによって生成されるようです。Object.prototype

Object.prototype == {
    __defineGetter__    : __defineGetter__()
    __defineSetter__    : __defineSetter__()
    __lookupGetter__    : __lookupGetter__()
    __lookupSetter__    : __lookupSetter__()
    constructor         : Object()
    hasOwnProperty      : hasOwnProperty()
    isPrototypeOf       : isPrototypeOf()
    propertyIsEnumerable: propertyIsEnumerable()
    toLocaleString      : toLocaleString()
    toString            : toString()
    valueOf             : valueOf()
    get __proto__       : __proto__()               //  getter
    set __proto__       : __proto__()               //  setter
};

__proto__オブジェクトがインスタンス化されたときに、このプロパティをハイジャックしてコード ブロックを実行できるかどうか疑問に思っています。プロパティを、元のアクセサーを呼び出して新しいインスタンスで__proto__作成する前にコードを実行するカスタム プロパティに置き換えるという考え方です。__proto__

それが理にかなっているなら!そうでない場合は、私がやっていることは次のとおりです。

pro = Object.prototype;
tmp = {};
Object.defineProperty(tmp, '__proto__',
    Object.getOwnPropertyDescriptor(pro, '__proto__')
);
delete pro.__proto__;
Object.defineProperty(pro, '__proto__',{
    get:function(){
        console.warn('intercepted Get __proto__');
        return tmp.__proto__;
    },
    set(p){
        console.warn('intercepted Set __proto__');
        tmp.__proto__ = p;
    }
});

まだ適切に動作するかどうかはわかりませんが、私が達成しようとしていることを示すための例にすぎません.

4

1 に答える 1

3

__proto__オブジェクトがインスタンス化されたときに、このプロパティをハイジャックしてコード ブロックを実行できるかどうか疑問に思っています。

いいえ__proto__。オブジェクトの作成時に、プロパティのアクセサーは呼び出されません。これらは、 get または set のときにのみ呼び出されます__proto__specを見ると、オブジェクトが作成されたときに何が起こるかがわかります。

ObjectCreate ( proto [ , internalSlotsList ])

引数proto (オブジェクトまたは null) を指定した抽象操作 ObjectCreate を使用して、新しい通常のオブジェクトの実行時作成を指定します。オプションの引数internalSlotsListは、オブジェクトの一部として定義する必要がある追加の内部スロットの名前のリストです。リストが提供されていない場合は、新しい空のリストが使用されます。この抽象操作は、次の手順を実行します。

  1. internalSlotsListが提供されなかった場合、 internalSlotsListを新しい空のリストにします。
  2. objを、 internalSlotsListの各名前の内部スロットを持つ新しく作成されたオブジェクトにします。
  3. objの本質的な内部メソッドを、9.1 で指定されたデフォルトの通常のオブジェクト定義に設定します。
  4. objの [[Prototype]] 内部スロットをprotoに設定します。
  5. objの [[Extensible]] 内部スロットをtrueに設定します。
  6. objを返します。

これはオブジェクトのプロトタイプ参照で__proto__ はないことを思い出してください。これはオブジェクト内の[[Prototype]]スロットであり、コードではアクセスできません。__proto__そのスロットの値にアクセスするための (Web のみの) 手段にすぎません。(一般的な方法は、ブラウザー外でも機能しますが、__proto__公式には機能しませんが、getPrototypeOf/ setPrototypeOfonObjectおよびです。) また、すべてのオブジェクトがから継承するわけではないため、Reflectすべてのオブジェクトが持っているわけではないことに注意してください。__proto__Object.prototype

var o1 = {};
console.log("__proto__" in o1); // true
var o2 = Object.create(null);   // No prototype
console.log("__proto__" in o2); // false
var o3 = Object.create(o2);     // Has a prototype, but still no link to Object.prototype
console.log("__proto__" in o3); // false

于 2016-07-05T11:17:54.907 に答える