有人可以解释这个Javascript方法吗?

use*_*242 24 javascript string reverse window

原始来源:http://twitter.com/tobeytailor/status/8998006366

(x=[].reverse)() === window // true
Run Code Online (Sandbox Code Playgroud)

我注意到这种行为会影响所有本机类型.到底发生了什么?

bob*_*nce 40

这与thisJavaScript中奇怪的绑定方式有关.

[].reverse
Run Code Online (Sandbox Code Playgroud)

reverse空列表上的方法.如果您通过以下方式之一致电:

[].reverse();
[]['reverse']();
([].reverse)();
Run Code Online (Sandbox Code Playgroud)

然后它以this绑定到列表实例的方式执行[].但如果你分开它:

x= [].reverse;
x();
Run Code Online (Sandbox Code Playgroud)

它在没有this绑定的情况下执行,因此this在函数中指向global(window)对象,这是JavaScript中最糟糕,最误导性的设计错误之一.

(x=[].reverse)()
Run Code Online (Sandbox Code Playgroud)

也正在做分离.赋值运算符返回它传递的相同函数对象,因此看起来它什么都不做,但它具有打破导致JavaScript绑定的有限特殊情况的副作用this.

所以你说:

Array.prototype.reverse.call(window)
Run Code Online (Sandbox Code Playgroud)

reverse与许多其他Array.prototype方法一样,ECMAScript定义它可以处理任何类似本机序列的对象.它使用数字字符串键(最多object.length)反转项目并返回对象.因此,它将返回为具有length属性的任何类型传入的对象.

window有一个长度属性,对应于window.frames.length,所以调用此方法this指向window将工作并返回window.理论上它可能仍然失败,因为:

  1. window被允许是"宿主对象"而不是"本地对象"; 在这种情况下,关于你可以传递给其他原型方法的保证并不一定适用; 和
  2. 如果窗口实际上有帧/ iframe,它会尝试反转它们的顺序,这不起作用,因为帧集合是只读的.

但是,在当前的浏览器中,前一种情况确实有效,而后一种情况无声地失败而没有错误,因此您仍然可以获得===window行为,而不是异常.

  • 绝对没有.它只是展示了JavaScript的许多意想不到的行为之一.如果我在实际代码中发现这个,我会担心! (3认同)
  • 这样做的一个可能原因可能是检查是否有其他脚本与窗口对象混淆(`window = open('http://google.com/')`就足够了).`var window =(x = [] .reverse)();`可以在本地恢复它. (2认同)