使用Javascript变量赋值上下文中的表达式与上下文之外的差异是什么?

SPOILER

我正在尝试solve problem #8这个Javascript注入游戏.

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

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

上面的代码片段与此之间的区别是什么

([].concat)()[0]

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

最佳答案 之前工作的原因是因为在先前版本的ECMAScript中指定了该值将是全局对象(即窗口).但是,从ECMAScript 5开始,此值现在未定义,这使得Array.prototype.concat引发错误.

在ES3中,如果使用此值undefined或null调用本机函数(例如使用func()调用它时),它将为函数提供全局对象.

在ES5中,本机函数的行为已更改,以便它获取实际的undefined或null值,即使您的代码不是严格模式.

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

GetValue()是一个内部函数,它从变量中获取引用的值 – 这在调用“direct”时不会被调用,但是当分配给另一个变量并使用其结果时,它确实被调用(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
点赞