关于javascript:我什么时候应该使用花括号进行ES6导入?

When should I use curly braces for ES6 import?

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

初始化状态

1
2
3
4
5
6
7
8
9
10
11
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;

在todoroucer.js中,我必须不使用大括号导入它:

1
import initialState from './todoInitialState';

如果用大括号将EDOCX1[0]括起来,我会得到以下代码行的错误:

Cannot read property todo of undefined

TodoReducer.js:

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

使用大括号的组件也会发生类似的错误。我想知道什么时候我应该使用花括号进行一次导入,因为很明显,当导入多个组件/模块时,您必须将它们括在花括号中,我知道。

编辑:

这里的so post没有回答我的问题,而是询问我应该或不应该在导入单个模块时使用大括号,或者我不应该在ES6中使用大括号来导入单个模块(显然不是这样,因为我看到了需要大括号的单个导入)


这是默认导入:

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

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

1
2
// A.js
export default 42

在这种情况下,导入时为其指定的名称并不重要:

1
2
3
4
// B.js
import A from './A'
import MyA from './A'
import Something from './A'

因为它总是能解决A的默认导出问题。

这是名为A的命名导入:

1
import { A } from './A'

只有当A包含名为A的命名导出时,它才起作用:

1
export const A = 42

在这种情况下,名称很重要,因为您要通过导出名称导入特定的对象:

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

要使这些功能正常工作,您可以将相应的命名导出添加到A

1
2
3
4
// A.js
export const A = 42
export const myA = 43
export const Something = 44

一个模块只能有一个默认导出,但可以有任意多个指定的导出(0、1、2或多个)。您可以将它们全部导入:

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

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

1
2
3
4
// A.js
export default 42
export const myA = 43
export const Something = 44

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

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

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

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


tl;dr:如果要导入非默认导出,则使用大括号。

更多详情请参阅上面的丹·阿布拉莫夫斯回答。


我想说,对于importes6关键字,还有一个星标符号值得一提。

enter image description here

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

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

你会得到:

enter image description here

When should I use curly braces for ES6 import?

当您只需要来自模块的特定组件时,括号是金黄色的,这使得像Webpack这样的bundler的足迹更小。


上面的DanAbramov回答解释了默认导出和命名导出。

使用哪一个?

引用david herman:ecmascript6倾向于单一/默认的导出样式,并为导入默认提供了最甜的语法。导入命名的导出可以甚至应该稍微简洁一些。

但是,在typescript中,由于重构,名为export的脚本更受欢迎。例如,如果默认导出一个类并对其重命名,则该类名称将仅在该文件中更改,而在其他引用中不会更改,并且在所有引用中都将重命名名为exports的类名称。命名导出对于实用程序也是首选。

全面使用你喜欢的任何东西。

附加的

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

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


如果你把import看作是节点模块、对象和破坏的语法糖,我会发现它非常直观。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 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';

通常在导出函数时,需要使用

1
if you have export const x

你用import {x} from ''

1
if you use export default const x

你需要使用import X from ''。这里你可以把x改成你想要的任何变量。


为了理解import语句中大括号的用法,首先,您必须理解ES6中引入的析构函数概念。

  • 对象破坏

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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
  • 阵列破坏

    1
    2
    3
    var [firstGame] = ['Gran Turismo', 'Burnout', 'GTA'];

    console.log(firstGame); // Gran Turismo

    使用列表匹配

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

    使用排列运算符

    1
    2
    3
    var [firstGame, ...rest] = ['Gran Turismo', 'Burnout', 'GTA'];
    console.log(firstGame);// Gran Turismo
    console.log(rest);// ['Burnout', 'GTA'];
  • 既然我们已经不再这样做了,那么在ES6中,您可以导出多个模块。然后可以像下面那样使用对象破坏

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

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

    您希望将导出的函数导入到index.js中;

    1
    2
    3
    4
        import {printFirstname, printLastname} from './module.js'

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

    您也可以使用类似这样的不同变量名

    1
    2
    3
    4
        import {printFirstname as pFname, printLastname as pLname} from './module.js'

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


    总结ES6模块:

    出口:

    您有两种类型的导出:

  • 命名出口
  • 默认导出,每个模块最多1个
  • Syntax:

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

    进口:

    导出类型(即命名导出或默认导出)影响如何导入某些内容:

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 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';

    感兴趣的事情:

  • 在大括号内使用逗号分隔的列表,该列表具有用于命名导出的导出的匹配名称。
  • 使用不带大括号的所选名称进行默认导出。
  • 别名:

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

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

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


    大括号()用于导入命名绑定,其背后的概念是破坏赋值。

    关于import语句如何与示例一起工作的一个简单演示,可以在我自己对类似问题的回答中找到,我们什么时候在javascript导入中使用""?