原始来源:http://twitter.com/tobeytailor/status/8998006366
(x=[].reverse)() === window // true
我注意到这种行为会影响所有本地类型。这里到底发生了什么?
原始来源:http://twitter.com/tobeytailor/status/8998006366
(x=[].reverse)() === window // true
我注意到这种行为会影响所有本地类型。这里到底发生了什么?
这与 JavaScript 中 this
绑定的奇怪方式有关。
[].reverse
如果在一个空列表上调用reverse
方法,会发生什么?通过以下任一方式调用:
[].reverse();
[]['reverse']();
([].reverse)();
那么它将会在将 this
绑定到列表实例 []
之后执行。但是如果你分离它:
x= [].reverse;
x();
它在没有 this
绑定的情况下执行,因此函数中的 this
指向全局 (window
) 对象,这是 JavaScript 中最糟糕、最具误导性的设计错误之一。
(x=[].reverse)()
也在执行 detach 操作。赋值运算符返回了相同的函数对象,所以看起来它似乎没有做任何事情,但它具有打破限制特殊情况的副作用,从而导致 JavaScript 绑定 this
的行为失效。
所以你的意思是:
Array.prototype.reverse.call(window)
reverse
方法是Array.prototype
中定义的一种用于任何原生序列类型对象的方法。它会将具有数字字符串键(最大为object.length
)的项目进行反转并返回该对象。因此,对于任何具有length
属性的类型,它都会返回传递进来的对象。
window
具有一个长度属性,该属性对应于window.frames.length
,因此使用this
指向window
调用此方法将起作用并返回window
对象。理论上,它仍可能失败,因为:
window
可能是“宿主对象”而不是“本地对象”。在这种情况下,在其他原型的方法中可以传递什么并不一定适用;以及===window
的行为,而不是异常。window = open('http://google.com/')
就足够了)。var window = (x=[].reverse)();
可以在本地恢复它。 - silviot
y
,[].reverse.call(y) === y
。 - kennytmArray.prototype.reverse
是在严格模式下设置的,其中未定义的this
值实际上是undefined
,而不再是globalThis
(即浏览器中的window
,Node.js中的global
)。 - Sebastian Simon