ECMAScript 2015官方规范Symbol.hasInstance writes:
此属性(指代Symbol.hasInstance)是不可写的 不可配置以防止可用于全局的篡改 暴露绑定函数的目标函数。
现在,甚至可以使用Object.defineProperty()覆盖不可写和不可配置的属性,实际上如果您尝试覆盖Symbol.hasInstance以始终返回true,那么它将会这样做。
我不明白这句话。
当你覆盖目标的Symbol.hasInstance以返回true时,可能暴露全局函数的情况是绑定函数的情况。当然,它会返回false,因为目标将其原型交换到绑定函数,因此绑定函数不是目标的实例。另外,据我所知,我认为它最终会导致全局范围的原因是因为绑定函数没有原型,因此无法在物理上成为目标函数的实例,所以如果你强制它作为实例,那么目标的原型被强制放在不存在的绑定原型上,它最终失败并将目标的this
放在全局范围内。但是,即使我将其设置为返回true,我仍然无法让它全局公开目标。
请注意,这是我想要做的事情,以便更好地理解JavaScript的内部工作原理。在实际应用中,我不希望全局公开目标。
我已经尝试过几个小时摆弄绑定函数的一系列代码片段,并且Symbol.hasInstance返回true但无济于事。我不能让它全局公开目标的功能和数据。如果有人更了解这一点,我们将非常感激。我撞到了一堵砖墙。
答案 0 :(得分:1)
让我们澄清一下,您所说的是规范的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中作用。