ECMAScript 2015 官方规范
Symbol.hasInstance
says(ECMA-262 6th Ed. §19.2.3.6):
[
属性]不可写且不可配置,以防止篡改,篡改可用于全局公开绑定函数的目标函数。Symbol.hasInstance
现在,即使是不可写和不可配置的属性也可以用
Object.defineProperty
覆盖,事实上,如果您尝试覆盖 Symbol.hasInstance
以始终返回 true,那么它就会这样做。
虽然我不明白这句话。
大概,当您覆盖目标的
Symbol.hasInstance
以返回 true 时,全局函数可能会被暴露的情况是绑定函数的情况。当然它会返回 false,因为目标将其原型交换到绑定函数上,因此绑定函数不是目标的实例。另外,根据我的最佳理解,我相信它最终会出现在全局范围内的原因是因为绑定函数没有原型,因此实际上不能成为目标函数的实例,因此如果您强制将其作为实例,则目标的原型被强制作用于不存在的绑定原型上,最终会失败并将目标的this
置于全局范围内。但是,即使我将其设置为返回 true,我仍然无法让它在全局范围内公开目标。
注意,这是我试图做的事情,以更好地理解 JavaScript 的内部工作原理。在实际应用中,我不想在全球范围内公开目标。
我已经尝试了好几个小时摆弄绑定函数的一系列代码片段,并且
Symbol.hasInstance
返回 true 但无济于事。我无法让它在全球范围内公开目标的功能和数据。如果有人更好地理解这一点,我们将不胜感激。我碰壁了。
让我们澄清一下,您正在谈论规范的第 19.2.3.6 部分,这是
Function.prototype[Symbol.hasInstance]
的规范。
最新版本规范中的文本是:
此属性不可写且不可配置,以防止可用于全局公开绑定函数的目标函数的篡改。
这说明你不能这样做:
// A malicious library loads here and overrides the function.
(function(){
Object.defineProperty(Function.prototype, Symbol.hasInstance, {
value: function(instance){
const context = this;
// Here, `this === SomeClass`
},
});
}();
// Some library loads here.
(function(){
function SomeClass(){}
const BoundClass = SomeClass.bind(null);
var tmp = {} instanceof BoundClass;
})();
因此,在这个示例中,如果属性是
configurable: true
,则恶意库将能够访问 SomeClass
,否则该属性将是完全私有的,并且范围在 IIFE 内。