Почему babel переписывает импортированный вызов функции (0, fn) (...)?
Учитывая входной файл, например
import { a } from 'b';
function x () {
a()
}
babel скомпилирует его для
'use strict';
var _b = require('b');
function x() {
(0, _b.a)();
}
но при компиляции в свободном режиме вызов функции выводится как _b.a();
Я провел некоторое исследование, в котором добавлен оператор запятой, в надежде, что есть комментарий, объясняющий это.
Код, отвечающий за его добавление, здесь.
Ответы
Ответ 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)()
.