ChatGPT解决这个技术问题 Extra ChatGPT

什么时候应该使用花括号进行 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) {
    // ...
}

我的带有花括号的组件也会发生类似的错误。我想知道何时应该对单个导入使用大括号,因为显然,在导入多个组件/模块时,您必须将它们括在大括号中,我知道。

here 的 Stack Overflow 帖子没有回答我的问题,而是我问何时我应该或不应该使用花括号来导入 single 模块,或者我永远不应该使用花括号在 ES6 中导入单个模块(这显然不是这种情况,因为我已经看到需要花括号的单个导入)。

不,不一样。谢谢
不,不一样。谢谢
如何确定 export 是 default 还是 named ?例如,reac-router-dom 包的链接?假设我已经安装了一个包并想导入,我将如何知道是否使用 {}

A
Alireza

这是默认导入:

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

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

// A.js
export default 42

在这种情况下,导入时分配给它的名称并不重要:

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

因为它将始终解析为 A默认导出

这是一个名为 A命名导入:

import { A } from './A'

仅当 A 包含名为 A命名导出时才有效:

export const A = 42

在这种情况下,名称很重要,因为您通过其导出名称导入特定事物:

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

要使这些工作,您需要向 A 添加一个对应的命名导出

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

一个模块只能有一个默认导出,但可以有任意数量的命名导出(零个、一个、两个或多个)。您可以将它们全部导入:

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

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

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

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

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

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

This is a great guide to ES modules, explaining the difference between default and named exports.


让模块具有单独的导出 export const myA = 43; export const Something = 44;export default { myA, Something } 有什么缺点吗?因此,当您导入时,您可以为模块中的所有内容使用 import A from './A';,或者import { Something } from './A';,这样您只能获得模块的一部分
这很好,但是已经有一种语法可以将所有命名的导出抓取到一个对象中:import * as AllTheThings
怎么样 - import 'firebase/storage';import 'rxjs/add/operator/map';。那实际上在做什么?
@kyw:这将执行模块但忽略导出的值。对副作用有用。
注意:当您执行 const A = 42; export default A; 时,您不能执行 import { A }; 这可能看起来很奇怪,并且在从命名导出重构为默认导出时可能会破坏您的导入(除非您删除花括号)。我想这有点合乎逻辑(叹气..),因为默认导出只导出一个值,而不是一个名称。 export default A 仅指 A 引用的值 42
p
prosti

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

https://i.stack.imgur.com/uCCXS.png

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

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

你会得到:

https://i.stack.imgur.com/sCZr6.png

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

当您只需要模块中的特定组件时,括号是金色的,这使得 webpack 之类的打包工具占用的空间更小。


import * as Mix from "./A";import A as Mix from "./A"; 是否相同?
“星号” 是什么意思? Wild cards
@PeterMortensen 术语星号,或加星号我相信我使用了“*”thefreedictionary.com/starred 一个星号。那是3年前的事了,但我认为是这样。
@PeterMortensen 加星标表示使用开始符号并从该文件/模块导入所有内容
@Alireza 我尝试将 const Imex = <div>Hello</div> console.log(a); 导入为 import Imex from "./Import"; 并在返回语句中 <Imex /> 显示错误并且 {Imex} 运行完美?
P
Peter Mortensen

Dan Abramov's answer 解释了默认导出命名导出

使用哪个?

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

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

总体使用你喜欢的任何东西。

额外的

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

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

Additional 行是很好的信息。如果您在未定义 export default 42 之类的名称的情况下进行导出,import A from './A' 就没有意义。
请确保不要误解大卫赫尔曼的报价。这并不意味着“在 ES6 中总是倾向于使用单一/默认导出”,而是“因为单一导出如此普遍,ES6 最好地支持默认值,我们给了它们最甜美的语法”。
P
Peter Mortensen

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

// 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' // The same thing - object functionA and functionB properties


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

P
Peter Mortensen

总结 ES6 模块:

出口:

您有两种类型的导出:

命名导出默认导出,每个模块最多一个

句法:

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

进口:

导出类型(即命名或默认导出)会影响导入方式:

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

句法:

// 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';

感兴趣的事情:

在大括号内使用逗号分隔的列表,并与命名导出的导出名称匹配。使用您选择的不带花括号的名称进行默认导出。

别名:

每当您想重命名命名导入时,都可以通过别名来实现。其语法如下:

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

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


P
Peter Mortensen

为了理解 import 语句中花括号的使用,首先要了解 ES6 中引入的 destructuring 的概念

对象解构 var bodyBuilder = { firstname: 'Kai', lastname: 'Greene', 昵称: 'The Predator' }; var {名字,姓氏} = bodyBuilder;控制台.log(名字,姓氏); // 凯格林名字 = '摩根';姓氏 = '阿斯特';控制台.log(名字,姓氏); // Morgan Aste 数组解构 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 Turismo console.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');

由于您正在显示与解构的比较,因此我将在您的最后一条评论中添加等效的解构比较:import {printFirstname as pFname, printLastname as pLname} from './module.js' 相当于:var foo = {printFirstname: 'p_f_n', printLastname: 'p_l_n'}; var { printFirstname:pFname, printLastname: pLname } = foo; pFname('Taylor'); pLname('Swift');
健美迷?
@TusharPandey 我是一名健美运动员
我认为在任何关于导入以及何时使用 curlys 与不使用它们的解释中,如果你没有提到对象破坏,那么你真的没有给出最好的解释。一旦我了解了解构,我就再也没有想过为什么要使用 curly,它只是直观地有意义。
import 语句中的花括号与解构无关。解构不适用于函数。但是我们在导入函数的导入语句中使用花括号(如果不是默认导出)。
P
Peter Mortensen

通常在导出函数时需要使用 {}。

如果你有

export const x

你用

import {x} from ''

如果你使用

export default const x

你需要使用

import x from ''

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


P
Peter Mortensen

花括号 ({}) 用于导入命名绑定,其背后的概念是 destructuring assignment

可以在我自己对 When do we use '{ }' in javascript imports? 上类似问题的回答中找到关于 import 语句如何与示例一起工作的简单演示。


A
Abhishek Kumar

花括号仅在命名导出时用于导入。如果导出为默认值,则不使用花括号进行导入。


M
Marcel Gruber

如果文件中有任何默认导出,则无需在导入语句中使用花括号。

如果文件中有多个导出,那么我们需要在导入文件中使用花括号,以便我们可以导入必要的。

您可以在下面的 YouTube 视频中找到何时使用花括号和默认语句的完全区别。 21. ES6 模块。使用导入/导出的不同方式,代码中的默认语法。 ES6 | ES2015


P
Peter Mortensen

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

例如,

文件播放器.js

export default vx;

文件 index.js

import vx from './player';

文件 index.js

https://i.stack.imgur.com/5HBFh.png

文件播放器.js

https://i.stack.imgur.com/iDyrd.png

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

https://i.stack.imgur.com/ObPk7.png