劫持.__ proto__

时间:2016-07-05 11:14:41

标签: javascript inheritance prototype proto

当对象被实例化时,无论是字符串/函数/等,都包含__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;
    }
});

无法判断它是否正常运行,但它只是一个例子,试图告诉你我想要实现的目标。

1 个答案:

答案 0 :(得分:2)

  

我想知道在实例化对象时是否有可能劫持此__proto__属性来执行代码块。

没有。创建对象时不会调用__proto__属性的访问者。只有在您获得或设置__proto__时才会调用它们。您可以通过查看the spec

来查看创建对象时会发生什么
  

ObjectCreate( proto [, internalSlotsList ])

     

带参数 proto (对象或null)的抽象操作ObjectCreate用于指定新普通对象的运行时创建。可选参数 internalSlotsList 是必须定义为对象一部分的其他内部插槽的名称列表。如果未提供列表,则使用新的空列表。此抽象操作执行以下步骤:

     
      
  1. 如果未提供 internalSlotsList ,请将 internalSlotsList 设为新的空列表。
  2.   
  3. obj 成为新创建的对象,其中 internalSlotsList 中的每个名称都有一个内部插槽。
  4.   
  5. obj 的基本内部方法设置为9.1中指定的默认普通对象定义。
  6.   
  7. obj 的[[Prototype]]内部插槽设置为 proto
  8.   
  9. obj 的[[Extensible]]内部插槽设为 true
  10.   
  11. 返回 obj
  12.   

回想一下,__proto__ 不是对象的原型参考;那是对象中的[[Prototype]]槽,在代码中无法访问。 __proto__只是一种(仅限Web)访问该槽中值的方法。 (一般的方式,也适用于浏览器以外的__proto__官方没有,getPrototypeOf / setPrototypeOf位于ObjectReflect。)另请注意并非所有对象都有__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