2016-07-05 2 views
0

オブジェクトがインスタンス化されるときは、それは文字列/関数/ etcであり、__proto__プロパティが含まれます。このプロパティは、オブジェクトがインスタンス化されるとき、コードブロックを実行するために、この__proto__プロパティをハイジャックすることが可能である場合、私は思ったんだけどハイジャック.__ proto__

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 
}; 

... Object.prototype__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; 
    } 
}); 

それはまだ正常に動作しますが、それは私が達成しようとしているものを試してみて、お見せするための唯一の例だかどうか言うことはできません。

+0

"* __proto__'プロパティが含まれています*" - まあ、いいえ、**継承**です。 'hasOwnProperty'プロパティがすべてのオブジェクトに含まれているとは言わないでしょうか? – Bergi

+0

いいえ、あなたはそれ以上のものをハイジャックすることはできません。* [それは良いことです](http://stackoverflow.com/a/13040748/1048572)。 – Bergi

答えて

2

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

いいえオブジェクトの作成時に__proto__プロパティのアクセサは呼び出されません。 __proto__を取得または設定したときにのみ呼び出されます。あなたは、オブジェクトがthe specを見ることで作成されたときに何が起こるかを見ることができます。

ObjectCreate(プロト [、internalSlotsList])

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

  1. 場合は、internalSlotsListは、新しい空のリストにしましょう。
  2. objを、internalSlotsListにそれぞれの名前の内部スロットを持つ新しく作成したオブジェクトにします。
  3. objの重要な内部メソッドを、9.1で指定されたデフォルトの通常のオブジェクト定義に設定します。
  4. [Prototype]の内部スロットをobjからのプロトタイプに設定します。
  5. [拡張可能]内部スロットをobjからに設定します。
  6. 返信obj__proto__は、オブジェクトのプロトタイプ参照ないこと

リコール。これはコード内でアクセスできないオブジェクト内の[[Prototype]]スロットです。 __proto__は、そのスロットの値にアクセスするための単なる(ウェブのみの)手段です。 (また、正式__proto__のに対し、外のブラウザで動作しますしない一般的な方法は、ObjectReflectgetPrototypeOf/setPrototypeOfである。)また、すべてのオブジェクトがObject.prototypeから継承していないためではないすべてのオブジェクトが__proto__を持っていることに注意してください:

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

+0

私はオブジェクトをインスタンス化するときにコンパイラが 'get __proto__'を呼び出すと仮定していますか? – LostInCyberSpace

+1

@LostInCyber​​Space:いいえ、エンジンはオブジェクトをインスタンス化するときにアクセサを呼び出しません。 –

+0

歓声が上がっています... – LostInCyberSpace

関連する問題