JavaScript中的间接函数调用

有东西像

f.call(...) f.apply(...) 

但是,那是这样的

 (1, alert)('Zomg what is this????!!!11') 

“1”在这种情况下似乎没有多大意义,下面的工作就好了:

 (null, alert)('Zomg what is this????!!!11') (1, null, alert)('Zomg what is this????!!!11') (undefined, alert)('Zomg what is this????!!!11') 

你能指出一个描述语法的ECMAScript的特定部分吗?

您只是使用逗号运算符 。

此运算符只从左到右评估其操作数,并从第二个返回值,例如:

 (0, 1); // 1 ('foo', 'bar'); // 'bar' 

在调用函数的上下文中,操作数的求值只会得到一个值,而不是引用,这将导致被调用的函数内的this值指向全局对象(或者在新的ECMAScript 5 Strict模式)。

例如:

 var foo = 'global.foo'; var obj = { foo: 'obj.foo', method: function () { return this.foo; } }; obj.method(); // "obj.foo" (1, obj.method)(); // "global.foo" 

正如你所看到的,第一个调用是直接调用, this method里面的this值会正确地引用obj (返回"obj.foo" ),第二个调用,由逗号运算符做出的评估会使this值指向全局对象(产生"global.foo" )。

这种模式现在已经变得相当stream行,间接调用eval ,这在ES5严格模式下可能是有用的,例如,获取对全局对象的引用(假设你处于非浏览器环境, window不可用):

 (function () { "use strict"; var global = (function () { return this || (1,eval)("this"); })(); })(); 

在上面的代码中,内部匿名函数将在一个严格的模式代码单元内执行,这将导致this值为undefined

|| 运算符现在将采用第二个操作数eval调用,这是一个间接调用,它将评估全局词法和variables环境中的代码。

但个人而言,在这种情况下,在严格模式下,我更喜欢使用Function构造函数来获取全局对象:

 (function () { "use strict"; var global = Function('return this')(); })(); 

函数构造函数创build的Function只有以“使用严格指令”开始时才是严格的,它们并不像函数声明或函数expression式那样“inheritance”当前上下文的严格性。

它是逗号运算符 ,它对两个操作数进行求值并返回第二个值。

所以,像(null, alert)这样的东西评估到alert函数,你可以立刻用圆括号来调用它。

在ECMA-262 (PDF)的第11.14节中有描述。

逗号运算符使expression式按顺序进行评估。 用圆括号包装expression式返回最后一个expression式的值。 所以(1, alert)("hello")在function上等价于:

 1; alert("hello"); 

除了我的头顶,我想不出有这个理由。