为什么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.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 )。
逗号运算符评估每个操作数(从左到右)并返回最后一个操作数的值。
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
原因。