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

给定一个input文件

import { a } from 'b'; function x () { a() } 

巴贝尔将编译它

 'use strict'; var _b = require('b'); function x() { (0, _b.a)(); } 

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

我已经做了一些研究,在那里添加逗号运算符,希望有一个解释它的评论。 负责添加它的代码在这里 。

(0, _b.a)()确保函数_b.a被调用到全局对象(或者如果严格模式被启用, undefined )。 如果您直接调用_b.a() ,则将_b.athis集合调用为_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 )。

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

 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 

现在,在foo方法中, this等于a (因为foo被附加到a )。 所以,如果直接调用a.foo( ),它将在控制台中logging为false

但是,如果你打电话(0, a.foo)() 。 expression式(0, a.foo)将评估每个操作数(从左到右)并返回最后一个操作数的值。 换句话说, (0, a.foo)相当于

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

由于这个函数不再附加到任何东西,所以它是全局对象window 。 这就是为什么在调用(0, a.foo)()时在控制台中logging为true原因。