Por que o babel reescreve a chamada de function importada para (0, fn) (…)?

Dado um arquivo de input como

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

O babel irá compilá-lo para

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

mas quando compilado no modo solto a chamada de function é saída como _b.a();

Eu fiz algumas pesquisas sobre onde o operador de vírgula é adicionado na esperança de que houvesse um comentário explicando isso. O código responsável por adicioná-lo está aqui .

(0, _b.a)() garante que a function _b.a seja chamada com this conjunto para o object global (ou se o modo estrito estiver ativado, para undefined ). Se você chamasse _b.a() diretamente, então _b.a é chamado com this definido como _b .

(0, _b.a)(); é equivalente a

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

(o , é o operador vírgula, consulte https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator ).

O operador vírgula avalia cada um de seus operandos (da esquerda para a direita) e retorna o valor do último operando.

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

Então, vamos ver um exemplo:

 var a = { foo: function() { console.log(this === window); } }; a.foo(); // Returns 'false' in console (0, a.foo)(); // Returns 'true' in console 

Agora, no método foo , this é igual a a (porque foo é anexado a a ). Então, se você chamar a.foo( ) diretamente, ela será registrada como false no console.

Mas, se você fosse chamada (0, a.foo)() . A expressão (0, a.foo) avaliará cada um dos seus operandos (da esquerda para a direita) e retornará o valor do último operando. Em outras palavras, (0, a.foo) é equivalente a

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

Como essa function não está mais anexada a nada, this é a window object global. É por isso que logar true no console quando chamada (0, a.foo)() .