为什么babel重写导入的函数调用(0,fn)(…)?


100

给定一个输入文件,例如

import { a } from 'b';

function x () {
  a()
}

巴别塔将其编译为

'use strict';

var _b = require('b');

function x() {
  (0, _b.a)();
}

但是在松散模式下编译时,函数调用输出为 _b.a();

我已经对添加逗号运算符的位置进行了一些研究,希望能对此发表评论。负责添加它的代码在这里


4
他们应该做_b.a.call()的很清楚。
Bergi 2015年

@Bergi我敢肯定,它们用(0,)的原因是为了节省转码后的代码空间。
安迪


Answers:


138

(0, _b.a)()确保在将函数设置为全局对象的_b.a情况下调用该函数this(或者,如果启用了严格模式,则为to undefined)。如果您要_b.a()直接呼叫,则将_b.a呼叫this设置为_b

(0, _b.a)(); 相当于

0; // Ignore result
var tmp = _b.a;
tmp();

(这,是逗号运算符,请参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator)。


3
感谢您的链接。经过了这么多次,最终决定找出正在发生的事情。
theflowersoftime's

@RobW我认为在很多情况下,var _a = (0, _b.a)在文件顶部添加然后进行调用_a会节省更多空间,您知道他们没有这样做吗?
安迪

1
@Andy您的建议可能有副作用,例如何时_b.a(动态)吸气剂。
罗布W

@RobW我明白了,所以您说的是要避免潜在的副作用,直到需要调用该函数为止。
安迪

请注意,模块始终是严格的代码,因此始终都是如此this === undefined,您甚至不必提及全局对象
Bergi,2016年

22

逗号运算符评估每个操作数(从左到右)并返回最后一个操作数的值。

console.log((1, 2)); // Returns 2 in console
console.log((a = b = 3, c = 4)); // Returns 4 in console

因此,让我们看一个例子:

var a = {
  foo: function() {
    console.log(this === window);
  }
};

a.foo(); // Returns 'false' in console
(0, a.foo)(); // Returns 'true' in console

现在,在foomethod中,this等于a(因为foo附加到a)。因此,如果a.foo(直接调用),它将登录false控制台。

但是,如果您打电话给(0, a.foo)()。该表达式(0, a.foo)将评估其每个操作数(从左到右)并返回最后一个操作数的值。换句话说,(0, a.foo)等于

function() {
  console.log(this === window);
}

由于此函数不再附加到任何东西,因此它this是全局对象window。这就是为什么true在call时登录控制台的原因(0, a.foo)()


console.log(this === window);在开发人员控制台中运行的日志不再打印。
kushdilip '19

2
这真让我震惊。这里的关键是逗号运算符“返回最后一个操作数的值”-这里的“值”是函数本身不包含其父对象-因此foo不再存在于a内。
martinp999
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.