Подтвердить что ты не робот

Почему babel переписывает импортированный вызов функции (0, fn) (...)?

Учитывая входной файл, например

import { a } from 'b';

function x () {
  a()
}

babel скомпилирует его для

'use strict';

var _b = require('b');

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

но при компиляции в свободном режиме вызов функции выводится как _b.a();

Я провел некоторое исследование, в котором добавлен оператор запятой, в надежде, что есть комментарий, объясняющий это. Код, отвечающий за его добавление, здесь.

4b9b3361

Ответ 1

(0, _b.a)() гарантирует, что функция _b.a вызывается с this, установленной для глобального объекта (или если строгий режим включен, 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).

Ответ 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

Теперь, в foo, this равен a (потому что foo привязан к a). Поэтому, если вы вызываете a.foo(), он будет записывать false в консоли.

Но если вы звонили (0, a.foo)(). Выражение (0, a.foo) будет оценивать каждый из его операндов (слева направо) и возвращает значение последнего операнда. Другими словами, (0, a.foo) эквивалентно

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

Поскольку эта функция больше не привязана ни к чему, ее this является глобальным объектом window. Вот почему он регистрирует true в консоли при вызове (0, a.foo)().