劫持 .__proto__
Hijacking .__proto__
对象实例化时,无论是string/function/etc,还是__proto__
属性。 属性 似乎是由 Object.prototype
中的 __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
};
我想知道是否可以劫持此 __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;
}
});
尚不能确定它是否正常工作,但这只是一个示例,旨在向您展示我正在努力实现的目标。
I'm wondering if it is possible to hijack this __proto__
property to execute a code block when an object is instantiated.
没有。 __proto__
属性 的访问器在创建对象时不会被调用。它们仅在您获取或设置 __proto__
时被调用。您可以通过查看 the spec:
查看创建对象时发生的情况
ObjectCreate (proto [ , internalSlotsList ])
The abstract operation ObjectCreate with argument proto (an object or null) is used to specify the runtime creation of new ordinary objects. The optional argument internalSlotsList is a List of the names of additional internal slots that must be defined as part of the object. If the list is not provided, a new empty List is used. This abstract operation performs the following steps:
- If internalSlotsList was not provided, let internalSlotsList be a new empty List.
- Let obj be a newly created object with an internal slot for each name in internalSlotsList.
- Set obj's essential internal methods to the default ordinary object definitions specified in 9.1.
- Set the [[Prototype]] internal slot of obj to proto.
- Set the [[Extensible]] internal slot of obj to true.
- Return obj.
回想一下 __proto__
不是 对象的原型引用;那是对象中的 [[Prototype]]
槽,它在代码中不可访问。 __proto__
只是一种(仅限网络)访问该插槽中的值的方法。 (在 Object
和 Reflect
上的 getPrototypeOf
/ setPrototypeOf
是 __proto__
官方不支持的通用方式并非所有对象都有 __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
对象实例化时,无论是string/function/etc,还是__proto__
属性。 属性 似乎是由 Object.prototype
中的 __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
};
我想知道是否可以劫持此 __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;
}
});
尚不能确定它是否正常工作,但这只是一个示例,旨在向您展示我正在努力实现的目标。
I'm wondering if it is possible to hijack this
__proto__
property to execute a code block when an object is instantiated.
没有。 __proto__
属性 的访问器在创建对象时不会被调用。它们仅在您获取或设置 __proto__
时被调用。您可以通过查看 the spec:
ObjectCreate (proto [ , internalSlotsList ])
The abstract operation ObjectCreate with argument proto (an object or null) is used to specify the runtime creation of new ordinary objects. The optional argument internalSlotsList is a List of the names of additional internal slots that must be defined as part of the object. If the list is not provided, a new empty List is used. This abstract operation performs the following steps:
- If internalSlotsList was not provided, let internalSlotsList be a new empty List.
- Let obj be a newly created object with an internal slot for each name in internalSlotsList.
- Set obj's essential internal methods to the default ordinary object definitions specified in 9.1.
- Set the [[Prototype]] internal slot of obj to proto.
- Set the [[Extensible]] internal slot of obj to true.
- Return obj.
回想一下 __proto__
不是 对象的原型引用;那是对象中的 [[Prototype]]
槽,它在代码中不可访问。 __proto__
只是一种(仅限网络)访问该插槽中的值的方法。 (在 Object
和 Reflect
上的 getPrototypeOf
/ setPrototypeOf
是 __proto__
官方不支持的通用方式并非所有对象都有 __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