原文来源:http: //twitter.com/tobeytailor/status/8998006366
(x=[].reverse)() === window // true
我注意到这种行为会影响所有本机类型。这里到底发生了什么?
原文来源:http: //twitter.com/tobeytailor/status/8998006366
(x=[].reverse)() === window // true
我注意到这种行为会影响所有本机类型。这里到底发生了什么?
这与this
绑定在 JavaScript 中的奇怪方式有关。
[].reverse
reverse
是空列表上的方法。如果您调用它,请通过以下方式之一:
[].reverse();
[]['reverse']();
([].reverse)();
然后它在this
绑定到列表实例的情况下执行[]
。但是如果你分离它:
x= [].reverse;
x();
它在没有this
-binding 的情况下执行,因此this
在函数中指向全局 ( window
) 对象,这是 JavaScript 最糟糕、最具误导性的设计错误之一。
(x=[].reverse)()
也在做分离。赋值运算符返回它传递的同一个函数对象,所以看起来它什么也没做,但它的副作用是打破了导致 JavaScript 绑定的有限特殊情况this
。
所以你说:
Array.prototype.reverse.call(window)
reverse
与许多其他Array.prototype
方法一样,由 ECMAScript 定义,用于处理任何本机类似序列的对象。它使用数字字符串键(最多object.length
)反转项目并返回对象。因此,它将返回为具有length
属性的任何类型传入的对象。
window
有一个长度属性,它对应于,因此使用指向window.frames.length
调用此方法将起作用并返回. 理论上它可能仍然会失败,因为:this
window
window
window
允许作为“宿主对象”而不是“本地对象”;在这种情况下,您可以传递给其他原型的方法的保证不一定适用;和但是,在当前的浏览器中,前一种情况确实有效,而后一种情况会静默失败而不会出现错误,因此您仍然会得到===window
行为而不是异常。