什么时候应该使用花括号进行 ES6 导入?
Posted
技术标签:
【中文标题】什么时候应该使用花括号进行 ES6 导入?【英文标题】:When should I use curly braces for ES6 import? 【发布时间】:2016-08-16 04:51:25 【问题描述】:这似乎很明显,但我发现自己对何时使用花括号在 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 中使用花括号来导入单个模块(这显然不是这种情况,因为我已经看到需要花括号的单个导入)。
【问题讨论】:
using brackets with javascript import syntax的可能重复 不,不一样。谢谢 ES6 module export options 或 Javascript (ES6), export const vs export default 的可能副本 不,不一样。谢谢 如何判断导出是默认还是命名?例如reac-router-dom 包的链接?假设我已经安装了一个包并想要导入,我将如何知道是否使用 【参考方案1】:这是一个默认导入:
// 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
,并将导出命名分别称为myA
和Something
。
// 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
仅指 42
引用的值 A
。【参考方案2】:
我想说import
ES6 关键字还有一个星号符号值得一提。
如果您尝试控制台记录 Mix:
import * as Mix from "./A";
console.log(Mix);
你会得到:
什么时候应该使用花括号进行 ES6 导入?
当您只需要模块中的特定组件时,括号是金色的,这使得 webpack 之类的打包器占用的空间更小。
【讨论】:
import * as Mix from "./A";
和 import A as Mix from "./A";
一样吗?
你所说的“加星标”是什么意思? Wild cards?
@PeterMortensen term star, or starred 我相信我用了“*”thefreedictionary.com/starred 一个星号。那是 3 年前的事了,但我认为是这样。
@PeterMortensen 加星标表示使用开始符号并从该文件/模块导入所有内容【参考方案3】:
Dan Abramov's answer 解释了默认导出和命名导出。
使用哪个?
引用 David Herman:ECMAScript 6 支持单一/默认导出样式,并为导入默认值提供了最甜美的语法。导入命名导出可以甚至应该稍微不那么简洁。
但是,在 TypeScript 中,由于重构,命名导出受到青睐。例如,如果您默认导出一个类并重命名它,则类名将仅在该文件中更改,而在其他引用中不会更改,命名为导出的类名将在所有引用中重命名。 命名导出也是实用程序的首选。
总体使用你喜欢的任何东西。
附加
默认导出实际上是一个名为default的命名导出,所以默认导出可以导入为:
import default as Sample from '../Sample.js';
【讨论】:
Additional
行是很好的信息。如果您在没有定义像 export default 42
这样的名称的情况下导出,import A from './A'
没有意义。
请确保不要误解大卫赫尔曼的报价。这并不意味着“倾向于总是在 ES6 中使用单一/默认导出”,而是“因为单一导出如此普遍,ES6 最好支持默认值我们给了他们最甜蜜的语法".【参考方案4】:
如果您认为 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';
【讨论】:
【参考方案5】:总结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';
感兴趣的事情:
-
在大括号内使用逗号分隔的列表,并与命名导出的导出匹配名称。
使用您选择的不带花括号的名称进行默认导出。
别名:
当您想要重命名命名导入时,可以通过aliases 来实现。其语法如下:
import importantData_1 as myData from './A';
现在我们已经导入了importantData_1
,但是标识符是myData
而不是importantData_1
。
【讨论】:
【参考方案6】:要想了解import
语句中花括号的使用,首先要了解ES6中引入的destructuring的概念
对象解构
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
数组解构
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,它只是直观地有意义。【参考方案7】:
通常在导出函数时需要使用 。
如果你有
export const x
你使用
import x from ''
如果你使用
export default const x
你需要使用
import x from ''
您可以在此处将 X 更改为您想要的任何变量。
【讨论】:
【参考方案8】:花括号 () 用于导入命名绑定,其背后的概念是 destructuring assignment
关于 import 语句如何与示例一起工作的简单演示可以在我自己对 When do we use ' ' in javascript imports? 的类似问题的回答中找到。
【讨论】:
【参考方案9】:大括号仅在命名导出时用于导入。如果导出为默认值,则不使用花括号进行导入。
【讨论】:
【参考方案10】:对于默认导出,我们在导入时不使用 。
例如,
文件 player.js
export default vx;
文件 index.js
import vx from './player';
文件 index.js
文件 player.js
如果我们想导入我们导出的所有内容,那么我们使用*
:
【讨论】:
【参考方案11】:如果文件中有任何默认导出,则不需要在导入语句中使用花括号。
如果文件中有多个导出,那么我们需要在导入文件中使用花括号,以便我们可以导入必要的。
您可以在下面的 YouTube 视频中找到使用花括号和默认语句的完全区别(非常重印度口音,包括滚动r 的...)。
21. ES6 Modules. Different ways of using import/export, Default syntax in the code. ES6 | ES2015
【讨论】:
以上是关于什么时候应该使用花括号进行 ES6 导入?的主要内容,如果未能解决你的问题,请参考以下文章