JavaScript中的间接函数调用

时间:2011-03-01 23:05:18

标签: javascript ecma262

有像

这样的东西
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的特定部分?

3 个答案:

答案 0 :(得分:45)

您只是使用The Comma Operator

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

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

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

例如:

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值将正确引用obj(返回"obj.foo"),第二个调用,由逗号运算符进行的评估将使this值指向全局对象(产生"global.foo")。

这种模式近来越来越流行,制作间接calls to eval,这在ES5严格模式下很有用,例如,获取对全局对象的引用(想象你是非-browser环境,window不可用):

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

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

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

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

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

使用Function构造函数创建的函数只有在使用严格使用指令时才是严格的,它们不像函数声明或函数表达式那样“继承”当前上下文的严格性。

答案 1 :(得分:8)

它是comma operator,它评估它的两个操作数并返回第二个操作数的值。

因此,(null, alert)之类的内容会计算alert函数,您可以使用括号立即调用该函数。

ECMA-262(PDF)第11.14节对此进行了描述。

答案 2 :(得分:3)

comma operator导致表达式按顺序进行评估。将表达式包装在括号中将返回最后一个表达式的值。所以(1, alert)("hello")在功能上等同于:

1;
alert("hello");

在我的脑海中,我想不出有这样做的理由。