JavaScript 中的间接函数调用

IT技术 javascript ecma262
2021-02-10 20:20:03

有这样的事情

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, 1); // 1
('foo', 'bar'); // 'bar'

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

例如:

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值指向全局对象(yielding "global.foo")。

这种模式最近很流行,要间接调用eval,这在 ES5 严格模式下很有用,例如,获取对全局对象的引用(假设您在非浏览器环境中,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构造函数创建的函数只有在以 Use Strict 指令开头时才是严格的,它们不会像函数声明或函数表达式那样“继承”当前上下文的严格性。

关于:“只会得到一个值,而不是一个参考”。这根本不是正在发生的事情。您会看到不同的行为,因为您在调用函数时没有使用点运算符如果您这样做,您会看到相同的行为:var temp = obj.method; temp();
2021-03-21 20:20:03
感谢 ECMAScript 链接
2021-03-23 20:20:03
很有意思。我的观点更行人:(1, obj.method) === obj.method // true
2021-04-04 20:20:03
@lwburk:我说的是规范,它将获得一个value,而不是一个Reference,看看逗号运算符返回的内容:“第 4 步。返回 GetValue(rref)。” 它使用GetValue抽象操作。您发布的示例确实是等效的,但略有不同,在这种情况下temp没有基础对象引用
2021-04-05 20:20:03
@lwburk,啊,你也可以看到你的例子并不完全等效,在 ES5 中:eval('foo')对 eval直接调用,但(1, eval)('foo')不是,这种情况与.属性访问器无关Kangax在这里很好地解释了这一点
2021-04-09 20:20:03

它是逗号运算符,它计算它的两个操作数并返回第二个操作数的值。

因此,类似于(null, alert)alert函数值,您可以立即使用括号调用函数。

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

逗号操作导致表达式顺序地进行评价。将表达式括在括号中会返回最后一个表达式的值。所以(1, alert)("hello")在功能上等同于:

1;
alert("hello");

在我的头顶上,我想不出这样做的理由。