JavaScript中的间接函数调用

JavaScript中的间接函数调用,javascript,ecma262,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') 您能

有这样的事情

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中描述该语法的特定部分吗?

它是,计算两个操作数并返回第二个操作数的值

因此,类似于
(null,alert)
的计算结果是
alert
函数,您可以使用括号立即调用该函数

(PDF)的第11.14节对此进行了描述。

导致表达式按顺序求值。将表达式括在括号中返回最后一个表达式的值。因此
(1,警报)(“hello”)
在功能上等同于:

1;
alert("hello");
我一时想不出这样做的理由。

你只是在使用

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

(0, 1); // 1
('foo', 'bar'); // 'bar'
var foo = 'global.foo';

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

obj.method();      // "obj.foo"
(1, obj.method)(); // "global.foo"
在调用函数的上下文中,操作数的求值只会得到一个值,而不是一个引用,这会导致被调用函数中的
this
值指向全局对象(或者在新的ECMAScript 5严格模式下它将是
未定义的

例如:

(0, 1); // 1
('foo', 'bar'); // 'bar'
var foo = 'global.foo';

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

obj.method();      // "obj.foo"
(1, obj.method)(); // "global.foo"
如您所见,第一个调用是直接调用,
方法中的
this
值将正确地引用
obj
(返回
“obj.foo”
),第二个调用,逗号操作符进行的计算将使
this
值指向全局对象(产生
“global.foo”

这种模式最近非常流行,为了使其成为间接模式,这在ES5严格模式下非常有用,例如,为了获取对全局对象的引用,(假设您在非浏览器环境中,
窗口
不可用):

在上述代码中,内部匿名函数将在严格模式代码单元内执行,这将导致
值为
未定义

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

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

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

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

感谢ECMAScript链接:“将只获取值,而不是引用”。事实并非如此。您看到了不同的行为,因为您在调用函数时没有使用。如果这样做,您将看到相同的行为:
var temp=obj.method;温度()
@lwburk:我说的是规范,它将得到一个值,而不是一个,看看逗号运算符返回什么:“步骤4.返回GetValue(rref)”,它使用抽象操作。您发布的示例确实是等效的,但略有不同,在这种情况下,
temp
是一个没有基本对象的引用。@lwburk,啊,您还可以看到您的示例在ES5中并不完全等效:
eval('foo')
是a,但
(1,eval)('foo')
不是,这种情况与
属性访问器无关。Kangax解释得很好,很有趣。我的观点要简单得多:
(1,obj.method)==obj.method//true
相关: