web-dev-qa-db-fra.com

Pourquoi Babel réécrit l'appel de fonction importé à (0, fn) (...)?

Étant donné un fichier d'entrée comme

import { a } from 'b';

function x () {
  a()
}

babel le compilera

'use strict';

var _b = require('b');

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

mais lorsqu'il est compilé en mode lâche, l'appel de fonction est généré sous la forme _b.a();

J'ai fait quelques recherches sur l'endroit où l'opérateur de virgule est ajouté dans l'espoir qu'un commentaire l'explique. Le code responsable de son ajout est ici .

92
Will Smith

(0, _b.a)() Garantit que la fonction _b.a Est appelée avec this défini sur l'objet global (ou si le mode strict est activé, sur undefined). Si vous deviez appeler _b.a() directement, alors _b.a Est appelé avec this réglé sur _b.

(0, _b.a)(); Équivaut à

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

(, est l'opérateur virgule, voir https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator ).

129
Rob W

L'opérateur virgule évalue chacun de ses opérandes (de gauche à droite) et renvoie la valeur du dernier opérande.

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

Alors, voyons un exemple:

var a = {
  foo: function() {
    console.log(this === window);
  }
};

a.foo(); // Returns 'false' in console
(0, a.foo)(); // Returns 'true' in console

Maintenant, dans la méthode foo, this est égal à a (car foo est attaché à a). Donc, si vous appelez a.foo() directement, il enregistrera false dans la console.

Mais si vous appelez (0, a.foo)(). L'expression (0, a.foo) évaluera chacun de ses opérandes (de gauche à droite) et renvoie la valeur du dernier opérande. En d'autres termes, (0, a.foo) est équivalent à

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

Puisque cette fonction n'est plus attachée à rien, son this est l'objet global window. C'est pourquoi il enregistre true dans la console lors de l'appel (0, a.foo)().

20
Huong Hk