2016-04-12 37 views
14

Powiedzmy mamy cztery moduły, A, B, C i DW składni "import" ES6, w jaki sposób moduł jest dokładnie oceniany?

W module A:

console.log("A evaluated") 
function AClass { 
    console.log("A constructor") 
} 
var aObj = new AClass() 
export default aObj; 

w module B:

import aObj from A 
export default "B" 

w module C:

import aObj from A 
export default "C" 

W module D:

import b from B 
import c from C 
import aObj from A 

Więc kiedy moduł D ocenia, ile razy będzie A evaluated i A constructor być drukowane w konsoli?

Czy to zachowanie opisane jest w standardzie ES6? Co powinienem zrobić, jeśli chcę, aby moduł był oceniany TYLKO RAZ, bez względu na to, ile razy jest importowany bezpośrednio lub pośrednio? Czy ktoś ma jakieś pomysły na ten temat?

+1

Po prostu mówiąc, nie powinieneś eksportować instancji, zawsze powinieneś wyeksportować klasę - lub jeśli potrzebujesz tylko obiektów, nie powinieneś używać klas. – Bergi

+0

@Bergi Dzięki, ale co powinienem zrobić, gdy potrzebuję zewnętrznej globalnej instancji singleton w różnych modułach ... Możliwe, że eksportowanie wystąpień jest jedyną metodą. –

+0

Możesz używać prostych literałów obiektowych do tworzenia singletonów. Nie ma potrzeby używania 'class'es. – Bergi

Odpowiedz

13

Gdy moduł D jest wykonywany, konsola będzie wydrukować tę wiadomość:

A evaluated 
A constructor 

co oznacza, że ​​moduł A oceniano tylko raz, nawet jeśli to było importowane wielokrotnie przez inne moduły.

Zasady oceny dla ES6 modules jest taka sama jak dla formatu commonjs:

  • Moduł jest kawałek kodu, który jest wykonywany po jej załadowaniu. Oznacza to, że jeśli moduł nie jest zawarty w pakiecie głównym, nie będzie on oceniany.
  • Moduły są singletonami. Jeżeli moduł jest importowany wielokrotnie tylko jeden instance z istnieje i jest on analizowany tylko raz przy obciążeniu

Zachowanie importowania sam przypadek modułu opisano HostResolveImportedModule Sekcji Specyfikacja ECMAScript 6.
Wymienia:

Operacja (operacja importu) należy idempotentnych jeśli kończy się normalnie. Każdorazowo nazywa się z określonym referencingModule, para specyfikator (import < > z < źródło >) jak argumentów musi zwrócić ten sam przypadek modułu nagrywania.

Zachowanie pojedynczej analizy czasu modułu opisano w ModuleEvaluation, punkt 4 i 5 za pomocą Evaluated logiczną flagi.
Każdy moduł ma flagę Evaluated, która sprawdza kod modułu tylko raz.