`export const` vs.` export default` in ES6


204

Ich versuche festzustellen, ob es große Unterschiede zwischen diesen beiden gibt, abgesehen davon, dass ich mit export defaultnur importieren kann :

import myItem from 'myItem';

Und mit export constkann ich tun:

import { myItem } from 'myItem';

Ich frage mich, ob es andere Unterschiede und / oder Anwendungsfälle gibt.


1
Mit constwird der Bezeichner schreibgeschützt. Bei primitiven Werten können Sie dies als unveränderlich betrachten. Beachten Sie, dass der Wert selbst nicht unveränderlich ist, sodass Objekte, Arrays usw. geändert werden können - nur nicht neu zugewiesen.
spmurrayzzz

4
@spmurrayzzz: FWIW, Importbindungen sind ebenso unveränderlich wie const.
Felix Kling

danke für die klarstellung @FelixKling, wusste das nicht
spmurrayzzz

@FelixKling: Zumindest von außen. Sie sind jedoch möglicherweise nicht konstant, die Exporte können geändert werden.
Bergi

@Bergi: Richtig, deshalb habe ich Importbindungen gesagt ;)
Felix Kling

Antworten:


326

Es ist ein benannter Export gegenüber einem Standardexport. export constist ein benannter Export, der eine oder mehrere const-Deklarationen exportiert.

Hervorheben: Hier kommt es auf das exportSchlüsselwort constan, mit dem eine oder mehrere const-Deklarationen deklariert werden. exportkann auch auf andere Deklarationen wie Klassen- oder Funktionsdeklarationen angewendet werden.

Standardexport ( export default)

Sie können einen Standardexport pro Datei durchführen. Beim Importieren müssen Sie einen Namen angeben und wie folgt importieren:

import MyDefaultExport from "./MyFileWithADefaultExport";

Sie können diesem Namen einen beliebigen Namen geben.

Benannter Export ( export)

Bei benannten Exporten können Sie mehrere benannte Exporte pro Datei haben. Importieren Sie dann die gewünschten Exporte in geschweifte Klammern:

// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";

// use MyClass, MyOtherClass, and MyClass2Alias here

Oder es ist möglich, einen Standard zusammen mit benannten Importen in derselben Anweisung zu verwenden:

import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";

Namespace-Import

Es ist auch möglich, alles aus der Datei auf ein Objekt zu importieren:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass, MyClasses.MyOtherClass and MyClasses.default here

Anmerkungen

  • Die Syntax bevorzugt Standardexporte als etwas präziser, da ihr Anwendungsfall häufiger vorkommt ( siehe Diskussion hier ).
  • Ein Standardexport ist eigentlich ein benannter Export mit dem Namen, defaultsodass Sie ihn mit einem benannten Import importieren können:

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";

24

export defaultBeeinflusst die Syntax beim Importieren des exportierten "Dings", beim Importieren von allem, was exportiert wurde, indem der Name importselbst ausgewählt wird, unabhängig davon, wie der Name beim Export war, einfach weil er als "Standard" markiert ist.

Ein nützlicher Anwendungsfall, den ich mag (und verwende), besteht darin, eine anonyme Funktion zu exportieren, ohne sie explizit benennen zu müssen. Nur wenn diese Funktion importiert wird, muss ihr ein Name gegeben werden:


Beispiel:

Exportieren Sie 2 Funktionen, eine davon ist default:

export function divide( x ){
    return x / 2;
}

// only one 'default' function may be exported and the rest (above) must be named
export default function( x ){  // <---- declared as a default function
    return x * x;
}

Importieren Sie die oben genannten Funktionen. Einen Namen für den defaulteinen erfinden:

// The default function should be the first to import (and named whatever)
import square, {divide} from './module_1.js'; // I named the default "square" 

console.log( square(2), divide(2) ); // 4, 1

Wenn die {}Syntax zum Importieren einer Funktion (oder Variablen) verwendet wird, bedeutet dies, dass alles, was importiert wurde, bereits beim Export benannt wurde. Daher muss es mit genau demselben Namen importiert werden, da sonst der Import sonst nicht funktioniert.


Fehlerhafte Beispiele:

  1. Die Standardfunktion muss zuerst importiert werden

    import {divide}, square from './module_1.js
  2. divide_1wurde nicht exportiert module_1.js, daher wird nichts importiert

    import {divide_1} from './module_1.js
  3. squarewurde nicht exportiert module_1.js, da {}die Engine angewiesen wird, explizit nur nach benannten Exporten zu suchen .

    import {square} from './module_1.js

Es bedeutet nicht, dass es eine einzige Sache exportiert. Sie können mehrere benannte und einen Standard im selben Modul haben. Standard bedeutet einfach genau das - es ist der Standardexport, wenn Sie beim Importieren den Namen nicht angeben, dh import something fromanstelle von import { somethingNamed } from.
Andris

Ich habe hier auch ein neues englisches Wort gelernt: "Erroneous" +1 dafür
Yuval Levy

12

Kleiner Hinweis: Bitte beachten Sie, dass beim Importieren aus einem Standardexport die Benennung völlig unabhängig ist. Dies wirkt sich tatsächlich auf Refactorings aus.

Angenommen, Sie haben eine Klasse Foowie diese mit einem entsprechenden Import:

export default class Foo { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export
import Foo from './Foo'

Wenn Sie nun Ihre FooKlasse umgestalten Barund die Datei auch umbenennen, berühren die meisten IDEs Ihren Import NICHT. Am Ende haben Sie also Folgendes:

export default class Bar { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export.
import Foo from './Bar'

Besonders in Typescript schätze ich benannte Exporte und das zuverlässigere Refactoring sehr. Der Unterschied ist nur das Fehlen des defaultSchlüsselworts und der geschweiften Klammern. Dies verhindert übrigens auch, dass Sie bei Ihrem Import einen Tippfehler machen, da Sie jetzt eine Typprüfung haben.

export class Foo { }

//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'

2
" 'Foo' muss der Klassenname sein. " - nein! Sie können dies genauso einfach tun import { Foo as Anything } from …wie import Anything from …mit Standardexporten.
Bergi

Dass Sie es mit einem umbenennen können , asist wirklich nicht der Punkt in diesem Quellkommentar. Vielen Dank für die Ablehnung; p
Philipp Sumi

1
Ich habe nicht abgelehnt, bin mir aber nicht sicher, ob dieses Argument überzeugend ist. Ich weiß nicht, ob ich möchte, dass meine IDE alle Importe umbenennt, wenn ein einzelnes Modul umgestaltet wird. Genau darum geht es bei der Modularisierung :-) Und es scheint eher ein IDE- "Problem" zu sein, kein Grund, den Exportstil zu wählen …
Bergi

Ich bin damit einverstanden, dass ich hier benannte Exporte für Entwickler-UX verwende - aber dann könnte man argumentieren, dass Typescript per se alles darüber ist. Ich überarbeite häufig und da ich normalerweise eine Klasse (in meinem Fall: Komponente reagieren) pro Datei habe, möchte ich unbedingt, dass die Importe einer umbenannten Komponente folgen, um keine Trennung zu erzeugen. Natürlich kann dies je nach Entwickler sinnvoll sein oder auch nicht.
Philipp Sumi

Ich habe einen Artikel gefunden , der dasselbe sagt. Vielleicht könnte eine vernünftige Position sein: Wir sollten export defaultdas Hauptobjekt eines Projekts exportieren, insbesondere aus einem npm-Paket (es ersetzt a module.exports =). Intern in einem Projekt ist es jedoch besser, nur benannte Exporte zu verwenden.
Paleo

7

Aus der Dokumentation :

Benannte Exporte sind nützlich, um mehrere Werte zu exportieren. Während des Imports kann derselbe Name verwendet werden, um auf den entsprechenden Wert zu verweisen.

In Bezug auf den Standardexport gibt es nur einen einzigen Standardexport pro Modul. Ein Standardexport kann eine Funktion, eine Klasse, ein Objekt oder etwas anderes sein. Dieser Wert ist als der "exportierte" Hauptwert zu betrachten, da er am einfachsten zu importieren ist.


0

Wenn Sie Standard festlegen, wird dies als Standardexport bezeichnet. Sie können nur einen Standardexport pro Datei durchführen und ihn in eine andere Datei mit einem beliebigen Namen importieren. Wenn Sie die Standardeinstellung "Name Export" nicht festlegen, müssen Sie sie in eine andere Datei mit demselben Namen und geschweiften Klammern importieren.


0

Ich hatte das Problem, dass der Browser es6 nicht verwendet.

Ich habe es behoben mit:

 <script type="module" src="index.js"></script>

Das Typmodul weist den Browser an, ES6 zu verwenden.

export const bla = [1,2,3];

import {bla} from './example.js';

Dann sollte es funktionieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.