Quando dovrei usare le parentesi graffe per l'importazione ES6?


766

Sembra ovvio, ma mi sono trovato un po 'confuso su quando usare le parentesi graffe per importare un singolo modulo in ES6. Ad esempio, nel progetto React-Native a cui sto lavorando, ho il seguente file e il suo contenuto:

initialState.js
var initialState = {
    todo: {
        todos: [
            {id: 1, task: 'Finish Coding', completed: false},
            {id: 2, task: 'Do Laundry', completed: false},
            {id: 2, task: 'Shopping Groceries', completed: false},
        ]
    }
};

export default initialState;

In TodoReducer.js, devo importarlo senza parentesi graffe:

import initialState from './todoInitialState';

Se allego le initialStateparentesi graffe tra parentesi graffe, ottengo il seguente errore per la seguente riga di codice:

Impossibile leggere la proprietà todo di undefined

TodoReducer.js:
export default function todos(state = initialState.todo, action) {
// ...
}

Errori simili accadono anche ai miei componenti con le parentesi graffe. Mi chiedevo quando dovrei usare le parentesi graffe per una singola importazione, perché ovviamente, quando si importano più componenti / moduli, è necessario racchiuderle tra parentesi graffe, che conosco.

Modificare:

Il post SO qui non risponde alla mia domanda, invece mi chiedo quando dovrei o non dovrei usare le parentesi graffe per importare un singolo modulo, o non dovrei mai usare le parentesi graffe per importare un singolo modulo in ES6 (apparentemente non è il caso, come ho visto importazione singola con parentesi graffe necessarie)



1
no, è diverso. grazie
TonyGW il

Risposte:


2270

Questa è un'importazione predefinita :

// B.js
import A from './A'

Funziona solo se Aha l' esportazione predefinita :

// A.js
export default 42

In questo caso non importa quale nome gli assegni durante l'importazione:

// B.js
import A from './A'
import MyA from './A'
import Something from './A'

Perché risolverà sempre qualunque sia l' esportazione predefinita di A.


Questa è un'importazione denominata chiamataA :

import { A } from './A'

Funziona solo se Acontiene un'esportazione denominata denominataA :

export const A = 42

In questo caso il nome è importante perché stai importando una cosa specifica con il suo nome di esportazione :

// B.js
import { A } from './A'
import { myA } from './A' // Doesn't work!
import { Something } from './A' // Doesn't work!

Per farlo funzionare, aggiungi un'esportazione denominata corrispondente a A:

// A.js
export const A = 42
export const myA = 43
export const Something = 44

Un modulo può avere solo un'esportazione predefinita , ma tutte le esportazioni nominate che desideri (zero, una, due o molte). Puoi importarli tutti insieme:

// B.js
import A, { myA, Something } from './A'

Qui, importiamo l'esportazione di default come A, e di nome esportazioni chiamati myAe Something, rispettivamente.

// A.js
export default 42
export const myA = 43
export const Something = 44

Possiamo anche assegnare loro nomi diversi durante l'importazione:

// B.js
import X, { myA as myX, Something as XSomething } from './A'

Le esportazioni predefinite tendono ad essere utilizzate per tutto ciò che normalmente ti aspetti di ottenere dal modulo. Le esportazioni con nome tendono ad essere utilizzate per utilità che potrebbero essere utili, ma non sono sempre necessarie. Tuttavia spetta a te scegliere come esportare le cose: ad esempio, un modulo potrebbe non avere alcuna esportazione predefinita.

Questa è un'ottima guida ai moduli ES, che spiega la differenza tra esportazioni predefinite e denominate.


4
C'è qualche svantaggio di avere un modulo con esportazioni individuali export const myA = 43; export const Something = 44;e un export default { myA, Something }? Quindi, quando importi, puoi o import A from './A';tutto per il modulo, o import { Something } from './A';così ottieni solo una parte del modulo
Michael,

12
E va bene, ma c'è già una sintassi per afferrare tutte le esportazioni di nome in un unico oggetto: import * as AllTheThings.
Dan Abramov

82
Chiaramente spiegato! Vorrei raddoppiare il voto per questa risposta.
Willa,

7
che dire di questo- import 'firebase/storage';o import 'rxjs/add/operator/map';. Cosa sta realmente facendo?
kyw,

9
@kyw: esegue il modulo ma ignora il valore esportato. Utile per gli effetti collaterali.
Dan Abramov,

84

Direi che c'è anche una notazione importspeciale per la parola chiave ES6 che vale la pena menzionare.

inserisci qui la descrizione dell'immagine

Se si tenta di eseguire il log della console Mix:

import * as Mix from "./A";
console.log(Mix);

Otterrete:

inserisci qui la descrizione dell'immagine

Quando dovrei usare le parentesi graffe per l'importazione ES6?

Le parentesi sono dorate quando sono necessari solo componenti specifici del modulo, il che rende impronte più piccole per bundler come il webpack.


4
La tua immagine è il cheat sheet perfetto per questa risposta particolare.
Rodrirokr,

1
Sono import * as Mix from "./A";e import A as Mix from "./A";lo stesso?
Shafizadeh,

40

La risposta di Dan Abramov sopra spiega le esportazioni predefinite e le esportazioni denominate .

Quale usare?

Citando David Herman : ECMAScript 6 favorisce lo stile di esportazione singolo / predefinito e fornisce la sintassi più dolce all'importazione del valore predefinito. L'importazione di esportazioni con nome può e dovrebbe anche essere leggermente meno concisa.

Tuttavia in TypeScript l'esportazione denominata è preferita a causa del refactoring. Ad esempio, se si esporta in modo predefinito una classe e la rinomina, il nome della classe cambierà solo in quel file e non negli altri riferimenti, con il nome della classe export sarà rinominato in tutti i riferimenti. Le esportazioni con nome sono preferite anche per le utility.

Uso generale qualunque cosa tu preferisca.

addizionale

L'esportazione predefinita è in realtà un'esportazione denominata con nome predefinito, quindi l'esportazione predefinita può essere importata come:

import {default as Sample} from '../Sample.js';

2
La Additionallinea è una buona informazione. import A from './A'non ha senso se esporti senza definire un nome come export default 42.
PGT,

8
Assicurati di non interpretare erroneamente la citazione di David Herman. Non significa " È preferibile utilizzare sempre le esportazioni singole / predefinite in ES6 ", ma piuttosto " Poiché le singole esportazioni sono così comuni, ES6 supporta meglio le impostazioni predefinite e abbiamo fornito loro la sintassi più dolce ".
Bergi,

15

Se pensi importsolo allo zucchero della sintassi per moduli di nodo, oggetti e destrutturazione, trovo che sia abbastanza intuitivo.

// bar.js
module = {};

module.exports = { 
  functionA: () => {},
  functionB: ()=> {}
};

 // really all that is is this:
 var module = { 
   exports: {
      functionA, functionB
   }
  };

// then, over in foo.js

// the whole exported object: 
var fump = require('./bar.js'); //= { functionA, functionB }
// or
import fump from './bar' // same thing, object functionA and functionB props


// just one prop of the object
var fump = require('./bar.js').functionA;

// same as this, right?
var fump = { functionA, functionB }.functionA;

// and if we use es6 destructuring: 
var { functionA } =  { functionA, functionB };
// we get same result

// so, in import syntax:
import { functionA } from './bar';

9

Per capire l'uso delle parentesi graffe nelle importdichiarazioni, in primo luogo, è necessario comprendere il concetto di distruzione introdotto in ES6

  1. Distruzione dell'oggetto

    var bodyBuilder = {
      firstname: 'Kai',
      lastname: 'Greene',
      nickname: 'The Predator'
    };
    
    var {firstname, lastname} = bodyBuilder;
    console.log(firstname, lastname); //Kai Greene
    
    firstname = 'Morgan';
    lastname = 'Aste';
    
    console.log(firstname, lastname); // Morgan Aste
  2. Ristrutturazione di array

    var [firstGame] = ['Gran Turismo', 'Burnout', 'GTA'];
    
    console.log(firstGame); // Gran Turismo

    Utilizzando la corrispondenza elenco

      var [,secondGame] = ['Gran Turismo', 'Burnout', 'GTA'];
      console.log(secondGame); // Burnout

    Utilizzando l'operatore di diffusione

    var [firstGame, ...rest] = ['Gran Turismo', 'Burnout', 'GTA'];
    console.log(firstGame);// Gran Turismo
    console.log(rest);// ['Burnout', 'GTA'];

Ora che ce l'abbiamo fatta a modo nostro, in ES6 puoi esportare più moduli. È quindi possibile utilizzare la distruzione degli oggetti come di seguito

Supponiamo che tu abbia un modulo chiamato module.js

    export const printFirstname(firstname) => console.log(firstname);
    export const printLastname(lastname) => console.log(lastname);

Si desidera importare le funzioni esportate in index.js;

    import {printFirstname, printLastname} from './module.js'

    printFirstname('Taylor');
    printLastname('Swift');

Puoi anche usare nomi di variabili differenti in questo modo

    import {printFirstname as pFname, printLastname as pLname} from './module.js'

    pFname('Taylor');
    pLanme('Swift');

Dal momento che stai mostrando confronti alla destrutturazione, aggiungerei il confronto equivalente alla destrutturazione al tuo ultimo commento: import {printFirstname as pFname, printLastname as pLname} from './module.js'è equivalente a:var foo = {printFirstname: 'p_f_n', printLastname: 'p_l_n'}; var { printFirstname:pFname, printLastname: pLname } = foo; pFname('Taylor'); pLname('Swift');
Adam Moisa

fan del bodybuilding?
Tushar Pandey,

@TusharPandey Sono un body builder
theTypan il

1
Penso a qualsiasi spiegazione dell'importazione e quando usare curlys invece di non usarli, se non stai menzionando la distruzione di oggetti, non stai davvero dando la migliore spiegazione. Una volta che ho imparato a conoscere la destrutturazione, non ho mai pensato al motivo per cui uso più il riccio, ha semplicemente un senso intuitivo.
Eric Bishard,

6

ES6Moduli di riepilogo :

le esportazioni:

Hai 2 tipi di esportazioni:

  1. Esportazioni nominate
  2. Esportazioni predefinite, massimo 1 per modulo

Sintassi:

// Module A
export const importantData_1 = 1;
export const importantData_2 = 2;
export default function foo () {}

importazioni:

Il tipo di esportazione (ovvero le esportazioni con nome o predefinite) influisce su come importare qualcosa:

  1. Per un'esportazione denominata dobbiamo usare parentesi graffe e il nome esatto come dichiarazione (cioè variabile, funzione o classe) che è stata esportata.
  2. Per un'esportazione predefinita possiamo scegliere il nome.

Sintassi:

// Module B, imports from module A which is located in the same directory

import { importantData_1 , importantData_2  } from './A';  // for our named imports

// syntax single named import: 
// import { importantData_1 } 

// for our default export (foo), the name choice is arbitrary
import ourFunction from './A';   

Cose di interesse:

  1. Utilizzare un elenco separato da virgole all'interno di parentesi graffe con il nome corrispondente dell'esportazione per l'esportazione denominata.
  2. Utilizzare un nome a scelta senza parentesi graffe per un'esportazione predefinita.

alias:

Ogni volta che si desidera rinominare un'importazione denominata, ciò è possibile tramite alias . La sintassi per questo è la seguente:

import { importantData_1 as myData } from './A';

Ora abbiamo importato importantData_1 ma l'identificatore è myDatainvece di importantData_1.


5

di solito quando esporti una funzione devi usare il {}

if you have export const x 

usate import {x} from ''

if you use export default const x 

devi usare import X from '' qui puoi cambiare X in qualunque variabile tu voglia


4

Le parentesi graffe ({}) vengono utilizzate per importare le associazioni denominate e il concetto alla base è l'assegnazione destrutturante

Una semplice dimostrazione di come funziona la dichiarazione di importazione con un esempio può essere trovata nella mia risposta a una domanda simile in Quando utilizziamo "{}" nelle importazioni javascript?


1
ottieni sicuramente il mio voto per la migliore risposta breve!
Eric Bishard,

0

Le parentesi graffe vengono utilizzate solo per l'importazione quando viene denominato export. Se l'esportazione è predefinita, le parentesi graffe non vengono utilizzate per l'importazione.


0

Per un'esportazione predefinita non utilizziamo {} durante l'importazione.

per esempio

player.js

export default vx;

index.js

import vx from './player';

index.js inserisci qui la descrizione dell'immagine

player.js inserisci qui la descrizione dell'immagine

Se vogliamo importare tutto ciò che esportiamo, utilizziamo * inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.