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

2022-08-30 05:14:46

给定一个输入文件,如

import { a } from 'b';

function x () {
  a()
}

巴别会把它编译成

'use strict';

var _b = require('b');

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

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

我对逗号运算符的添加位置进行了一些研究,希望有一条评论可以解释它。负责添加它的代码在这里


答案 1

(0, _b.a)()确保调用函数时设置为全局对象(或者如果启用了严格模式,则设置为 )。如果要直接调用,则调用时设置为 。_b.athisundefined_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)。,


答案 2

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

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

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

但是,如果您被呼叫.表达式将计算其每个操作数(从左到右),并返回最后一个操作数的值。换句话说,等效于(0, a.foo)()(0, a.foo)(0, a.foo)

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

由于此函数不再附加到任何内容,因此它是 全局对象 。这就是为什么它在调用 时登录到控制台的原因。thiswindowtrue(0, a.foo)()