这似乎很明显,但我发现自己对何时使用花括号在 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 中导入单个模块(这显然不是这种情况,因为我已经看到需要花括号的单个导入)。
这是默认导入:
// 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.
我想说还有一个值得一提的 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";
是否相同?
const Imex = <div>Hello</div> console.log(a);
导入为 import Imex from "./Import";
并在返回语句中 <Imex />
显示错误并且 {Imex}
运行完美?
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'
就没有意义。
如果您认为 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';
总结 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
。
为了理解 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');
通常在导出函数时需要使用 {}。
如果你有
export const x
你用
import {x} from ''
如果你使用
export default const x
你需要使用
import x from ''
在这里,您可以将 X 更改为您想要的任何变量。
花括号 ({}) 用于导入命名绑定,其背后的概念是 destructuring assignment
可以在我自己对 When do we use '{ }' in javascript imports? 上类似问题的回答中找到关于 import 语句如何与示例一起工作的简单演示。
花括号仅在命名导出时用于导入。如果导出为默认值,则不使用花括号进行导入。
如果文件中有任何默认导出,则无需在导入语句中使用花括号。
如果文件中有多个导出,那么我们需要在导入文件中使用花括号,以便我们可以导入必要的。
您可以在下面的 YouTube 视频中找到何时使用花括号和默认语句的完全区别。 21. ES6 模块。使用导入/导出的不同方式,代码中的默认语法。 ES6 | ES2015
对于默认导出,我们在导入时不使用 { }。
例如,
文件播放器.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
不定期副业成功案例分享
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';
。那实际上在做什么?const A = 42; export default A;
时,您不能执行import { A };
这可能看起来很奇怪,并且在从命名导出重构为默认导出时可能会破坏您的导入(除非您删除花括号)。我想这有点合乎逻辑(叹气..),因为默认导出只导出一个值,而不是一个名称。export default A
仅指A
引用的值42
。