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");
除了我的头顶,我想不出有这个理由。