2016-09-01 20 views
8

Rozumiem, że przy eksporcie modułu ES6 następuje powiązanie między tym, co jest eksportowane, a tym, co importowane, tak że po wyeksportowaniu zmiennej, importowana zmienna wykaże tę zmianę.Czy istnieje różnica między `domyślnym eksportem x` i` eksportem {x jako domyślnym?}?

Jednak przeczytałem również, że zaimportowana zmienna w określonych okolicznościach nosi powiązanie z eksportowaną zmienną.

Mam konkretne pytanie o to, czy istnieje różnica w jaki sposób eksportowane zmienne są związane w następujących dwóch scenariuszy ...

// Scenario #1 
let a = 5; 
export default a; 

// Scenario #2 
let a = 5; 
export { a as default }; 
+0

R podniecony: [Jaka jest różnica między importowaniem funkcji lub deklaracji funkcji z modułu ES6?] (http://stackoverflow.com/q/35223111/1048572) – Bergi

Odpowiedz

8

Nie są one takie same w ogólnym przypadku, chociaż mogą zachowywać się tak samo w przypadku funkcji i klas.

let a = 4; 
export default a; 

jest równoważna

let a = 4; 
let *default* = a; 
export {*default* as default}; 

oznacza, że ​​

let a = 4; 
export default a; 

a = 5; 

pozostawi 4 jak eksportowanego wartości, choć a wewnątrz modułu uległa zmianie, natomiast export {a as default}; stałaby eksportowany wartości 5.

ECMAScript Spec definiuje trzy różne formy export default, niektóre przykłady w tej tabeli http://www.ecma-international.org/ecma-262/7.0/#table-42 a zasadniczo zgłoszenia składni eksporcie: http://www.ecma-international.org/ecma-262/7.0/#sec-exports

export default HoistableDeclaration 
export default ClassDeclaration 
export default [lookahead ∉ { function, class }] AssignmentExpression; 

z HoistableDeclaration w tym przypadku mapowania deklaracje funkcji i deklaracje generatorów.

Jeśli spojrzymy na spec gdzie definiuje mapowanie nazw zmiennych w pliku, do eksportowanych nazw, http://www.ecma-international.org/ecma-262/7.0/#sec-exports-static-semantics-exportentries

ExportDeclaration: export default HoistableDeclaration 
    Let names be BoundNames of HoistableDeclaration. 
    Let localName be the sole element of names. 
    Return a new List containing the Record {[[ModuleRequest]]: null, 
    [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}. 

ExportDeclaration: export default ClassDeclaration 
    Let names be BoundNames of ClassDeclaration. 
    Let localName be the sole element of names. 
    Return a new List containing the Record {[[ModuleRequest]]: null, 
    [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}. 

ExportDeclaration: export default AssignmentExpression; 
    Let entry be the Record {[[ModuleRequest]]: null, [[ImportName]]: null, 
    [[LocalName]]: "*default*", [[ExportName]]: "default"}. 
    Return a new List containing entry. 

    NOTE 
    "*default*" is used within this specification as a synthetic name for anonymous default export values. 

BoundNames tutaj zwraca nazwę funkcji lub klasy przekazanego jako wartość, więc w dwóch pierwszych przypadkach

export default function fn(){} 
// or 
export default function* fn(){} 
// or 
export default class cls {} 

wyeksportuje żywo wiązania dla zmiennych fn lub cls.

Można również zrobić

export default function(){} 
// or 
export default function*(){} 
// or 
export default class {} 

w tym przypadku, to będzie eksportować wartości bez żywych powiązań, gdyż nie mają nazwy.

W tym ostatnim przypadku z export default AssignmentExpression ; jest to, co spełnia Twój przykład z export default a;. Możesz zauważyć, że ma on [[LocalName]]: *default*, a nie [[LocalName]]: localName, podobnie jak inne. Dzieje się tak, ponieważ export default a; nie rozpoznaje a jako eksportowanej nazwy, przetwarza ją jako bieżącą wartość a będącą eksportowaną wartością. To nie różni się od export default 4;, nie ma nazwy z punktu widzenia specyfikacji.

Zasadniczo

export default function fn(){} 

odpowiada

function fn(){} 
export {fn as default}; 

ale

let a = 4; 
export default a; 

nie odpowiada:

let a = 4; 
export {a as default}; 
+0

OK, 'let a = 4; export default a' jest równoważne 'export default 4'. Czy "[[nazwa_lokalna]]: nazwa_lokalna' /" [[nazwa_lokalna]]: * wartość domyślna * 'powoduje jakiekolwiek różnice praktyczne (podczas importowania, podglądu na żywo tylko do odczytu itp.)? – ftor

+0

Masz rację, dodano przykład pokazujący, dlaczego ta różnica ma znaczenie. – loganfsmyth

0

Jak stwierdzono w:

Mozilla Docs

scenariuszu 1

Jest używany do nazwanych eksportów

// module "my-module.js" 
export function cube(x) { 
    return x * x * x; 
} 
const foo = Math.PI + Math.SQRT2; 
export { cube, foo }; 

Scenariusz 2

Jest używany do eksportowania pojedynczą wartość lub mieć wartość zastępczego modułu

// module "my-module.js" 
export default function cube(x) { 
    return x * x * x; 
} 

Nie ma specyfikacja o różnicy w wydajności chociaż.

+2

Nie sądzę, że OP pyta o składnię dla nazwanych eksportów, a konkretnie 'eksportuj domyślne X' kontra' eksportuj {X jako domyślny}; '. – loganfsmyth

Powiązane problemy