2015-08-28 4 views
67

Dato un file di input comePerché babel riscrive la chiamata della funzione importata su (0, fn) (...)?

import { a } from 'b'; 

function x() { 
    a() 
} 

babel compilerà a

'use strict'; 

var _b = require('b'); 

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

ma quando compilato in modalità sciolto la chiamata di funzione viene emesso come _b.a();

Ho fatto qualche ricerca in dove viene aggiunto l'operatore virgola nella speranza c'era un commento che lo spiegava. Il codice responsabile per l'aggiunta è here.

+3

Avrebbero dovuto fare '_b.a.call()' per rendere chiara l'intenzione. – Bergi

+0

@Bergi Sono sicuro che il motivo per cui (0,) è di risparmiare spazio nel codice transpiled. – Andy

+2

vedere anche [L'operatore virgola influenza il contesto di esecuzione in Javascript?] (Http://stackoverflow.com/q/36076794/1048572) – Bergi

risposta

93

(0, _b.a)() assicura che la funzione viene chiamata con _b.athis impostato all'oggetto globale (o modalità rigorosa è attivata, per undefined). Se si dovesse chiamare direttamente _b.a(), viene chiamato _b.a con this impostato su _b.

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

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

(la , è l'operatore virgola, vedi https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator).

+2

grazie per il collegamento. passato così tante volte e alla fine ho deciso di scoprire cosa stava succedendo. –

+0

@RobW Penso che aggiungere 'var _a = (0, _b.a)' all'inizio del file e poi chiamare '_a' farebbe risparmiare più spazio in molti casi, qualsiasi idea non l'abbiano fatto? – Andy

+1

@Andy Il tuo suggerimento potrebbe avere effetti collaterali, ad es. quando '_b.a' è un getter (dinamico). –

9

L'operatore virgola valuta ciascuno dei suoi operandi (da sinistra a destra) e restituisce il valore dell'ultimo operando.

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

Così, per non vedere un esempio:

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

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

Ora, in foo metodo, this è uguale a a (perché foo è attaccato a a). Quindi, se si chiama a.foo(), verrà registrato false nella console.

Ma, se si chiamano (0, a.foo)(). L'espressione (0, a.foo) valuterà ciascuno dei suoi operandi (da sinistra a destra) e restituirà il valore dell'ultimo operando. In altre parole, (0, a.foo) è equivalente a

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

Poiché questa funzione non è collegato a nulla, la sua this è l'oggetto globale window. Ecco perché registra true in console quando chiama lo (0, a.foo)().