4

剧透

我正在尝试解决这个 Javascript 注入游戏的问题 #8。

Erling Ellingsen的评论之一中,我发现了这个有趣的片段。

(_=[].concat)()[0]

上面的片段和这个有什么区别,

([].concat)()[0]

分配给变量时会发生什么变化[].concat?显然,他只是试图访问全局窗口对象,但是这两者的评估有何不同呢?

4

1 回答 1

2

this以前工作的原因是因为在以前版本的 ECMAScript 中指定 this 值将是全局对象(即window)。但是,从 ECMAScript 5 开始, this 值为 now undefined,这使得 makeArray.prototype.concat抛出错误。

在 ES3 中,如果一个原生函数被使用or的this值调用(例如当你使用 调用它时),它将为函数提供全局对象。undefinednullfunc()

在 ES5 中,本机函数的行为已更改,以便它获取实际值undefinednull值,即使您的代码未处于严格模式。


两者的区别在于,一个是函数的值,因此被间接调用,而另一个是对函数的引用。

GetValue()是一个从变量中获取引用值的内部函数 - “直接”调用时不会调用它,但是当分配给另一个变量并使用其结果时,它确实被调用(source)。

两者之间差异的一个臭名昭著的例子是使用时eval()

var a = 0;
function test()
{   var a = 1, b;
    console.log(eval("a")); // 1
    console.log((b=eval)("a")); // 0
}
test();

但是,在您的示例中,它的工作原理如下:

var a = [].concat;
// called as variable, not property
a(); // therefore it's global

// same as the following, as all these expressions call GetValue() interally
(0, [].concat)();
(random = [].concat)();
([].concat || 0)();

// but this doesn't work
[].concat(); // `this` is the new array, not global object
于 2013-10-09T05:45:58.910 回答