什么时候应该使用花括号进行ES6导入?

这似乎很明显,但我发现自己有点困惑何时在ES6中使用花括号来导入单个模块。例如,在我正在进行的React-Native项目中,我有以下文件及其内容:

文件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;

在TodoReducer.js,我必须在没有花括号的情况下导入它:

import initialState from './todoInitialState';

如果我将initialState括在花括号中,则以下代码行会出现以下错误:

无法读取未定义的属性todo

文件TodoReducer.js

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

类似的错误也发生在我使用花括号的组件上。我想知道什么时候应该对单个导入使用花括号,因为很明显,当导入多个组件/模块时,你必须用花括号将它们括起来,这我知道。

堆栈溢出后这里没有回答我的问题,相反,我问我应该或不应该使用花括号来导入单一模块,或者我不应该使用花括号来导入ES6中的单个模块(显然不是这样,因为我见过需要花括号的单导入)。

300238 次浏览

这是一个默认导入

// B.jsimport A from './A'

只有当A具有默认导出时才有效:

// A.jsexport default 42

在这种情况下,导入时分配给它的名称无关紧要:

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

因为它总是会解析为A默认导出


这是一个命名导入调用#0

import { A } from './A'

仅当A包含命名导出调用#0时才有效:

export const A = 42

在这种情况下,名称很重要,因为您正在导入出口名称的特定事物

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

要使这些工作,您需要将对应的命名导出添加到A

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

一个模块只能有一个默认导出,但可以有你想要多少名字就有多少(零、一、二或多)。您可以将它们一起导入:

// B.jsimport A, { myA, Something } from './A'

在这里,我们将默认导出导入为A,并分别将命名导出称为myASomething

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

我们还可以在导入时为它们分配不同的名称:

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

默认导出往往用于您通常希望从模块中获得的任何内容。命名导出往往用于可能方便但并非总是必要的实用程序。但是,您可以选择如何导出内容:例如,一个模块可能根本没有默认导出。

这是一本很好的ES模块指南,解释了默认导出和命名导出之间的区别。

Dan Abramov的回答解释了默认导出指定出口

用哪个?

引用David Herman的话ECMAScript 6支持单一/默认导出样式,并为导入默认值提供了最甜蜜的语法。导入命名导出可以甚至应该稍微不那么简洁。

然而,在TypeScript中,由于重构,命名导出受到青睐。例如,如果您默认导出一个类并重命名它,类名将仅在该文件中更改,而不在其他引用中更改,命名导出类名将在所有引用中重命名。命名导出也是公用事业的首选。

使用任何你喜欢的。

额外

默认导出实际上是一个名为default的命名导出,因此默认导出可以导入为:

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

我想说还有一个值得一提的import ES6关键字的星号符号。

在此处输入图片描述

如果您尝试控制台日志混合:

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

您将获得:

在此处输入图片描述

什么时候应该使用花括号进行ES6导入?

当您只需要模块中的特定组件时,括号是金色的,这使得webpack等捆绑器的占用空间更小。

如果你认为import只是Node.js模块、对象和解构的语法糖,我发现它非常直观。

// bar.jsmodule = {};
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 }// Orimport fump from './bar' // The same thing - object functionA and functionB properties

// Just one property of the objectvar 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';

为了理解花括号在import语句中的使用,首先,您必须理解ES6中引入的解构的概念

  1. 对象解构

    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. 阵列解构

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

    使用列表匹配

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

    使用传播运算符

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

现在我们已经解决了这个问题,在ES6中,您可以导出多个模块。然后您可以像下面这样使用对象解构。

假设您有一个名为module.js的模块

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

您想将导出的函数导入index.js

    import {printFirstname, printLastname} from './module.js'
printFirstname('Taylor');printLastname('Swift');

你也可以像这样使用不同的变量名

    import {printFirstname as pFname, printLastname as pLname} from './module.js'
pFname('Taylor');pLanme('Swift');

通常,当您导出函数时,您需要使用{}。

如果你有

export const x

您使用

import {x} from ''

如果您使用

export default const x

你需要使用

import x from ''

在这里,您可以将X更改为您想要的任何变量。

花括号({})用于导入命名绑定,其背后的概念是解构赋值

导入语句如何与示例一起工作的简单演示可以在我自己对我们什么时候在JavaScript导入中使用'{}'?中类似问题的回答中找到。

总结ES6模块:

出口:

您有两种类型的导出:

  1. 指定出口
  2. 默认导出,每个模块最多一个

语法:

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

进口:

类型的出口(即命名或默认导出)影响如何导入:

  1. 对于命名的导出,我们必须使用花括号和确切名称作为导出的声明(即变量、函数或类)。
  2. 对于默认导出,我们可以选择名称。

语法:

// 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 arbitraryimport ourFunction from './A';

感兴趣的事情:

  1. 在大括号内使用逗号分隔的列表,并将匹配名称的导出用于命名导出。
  2. 为默认导出使用您选择的不带花括号的名称。

别名:

每当您想重命名命名导入时,都可以通过别名进行。语法如下:

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

现在我们导入了importantData_1,但标识符是myData而不是importantData_1

花括号仅在命名导出时用于导入。如果导出是默认的,则花括号不用于导入。

对于默认导出,我们在导入时不使用{}。

例如,

文件player.js

export default vx;

文件index.js

import vx from './player';

文件index.js

在此输入图片描述

文件player.js

在此输入图片描述

如果我们想导入我们导出的所有内容,那么我们使用*

在此输入图片描述