export/import 语句中有和没有大括号符号有什么区别?
What is the difference between with and without curly bracket notation in export/import statements?
我是 ES6 的新手,对 classes 的导出和导入方式有点困惑。似乎许多不同的符号都是有效的,但工作方式不同。
我在src/web-api.js
中写了一个这样的class:
class WebApi {
// ...
}
export { WebApi };
我导入的是:
import { WebApi } from './src/web-api.js'
这工作正常,但在我尝试没有大括号的同样的事情之前它没有工作:
export WebApi; // Tells me '{' expected
import WebApi from './src/web-api.js'; // No syntax error but WebApi is undefined
即使在 MDN documentation for export 上,符号 export expression;
似乎是有效的。
同样,这是在我的应用程序文件中导入 React 的方式:
import React, { Component } from 'react';
为什么一个 class 有大括号,另一个没有大括号?一般来说,我怎么知道什么时候使用和不使用大括号?
大括号只是语法糖。它将使用变量名作为对象键,例如:
const a = 1;
const test = {a}; // same as {a: 1};
它也可以用来通过变量名来解构对象。它将检查对象是否具有与变量名具有相同值的属性,如果找到则输出一个值:
const test = {a: 1};
const {a} = test; // a = 1
在模块中,一般用例是当您导入时通常有大括号,因为模块被导入为 MODULE.function
或 MODULE.class
。先看exports会更直观:
对于导出,它使用了我之前提到的语法糖 - 您将其作为对象导出。当你做 export { WebApi };
时,你真正在做的是 export {WebApi: WebApi}
。这使得访问内容变得更容易,因为您现在可以 'MODULE.WebApi' 访问 class 而不是让它不必要地污染命名空间。这也是所有导出所必需的!
继续导入,您在导入语句中所做的实质上是解构模块对象并选择 属性 保存到同名变量中。在您的情况下,当您执行 import {WebApi} from './src/web-api.js'
时,您会执行类似 import WebApi = web-api.js['WebApi'] from './src/web-api.js'
的操作(这不是有效的语法,只是为了向您展示它在后台执行的操作)。这也是正确导入模块 functions/classes 所必需的。还有一个导入整个模块的选项,就像 NodeJS 一样:import * as ModuleName from './src/module.js'
。这会将所有导出的 functions/classes 放入 ModuleName 对象中,以便将其视为普通模块。
但是,如果模块具有 default
导出,则导入和导出不需要大括号。例如,React 的文件中可能有 export default React
- 这就是为什么当你做 import React from 'react'
时不需要用大括号括起来的原因
希望我没有太混乱,如果我能澄清任何事情,请告诉我!
ES6 提供了多种 方式来通过import/export 管理模块。但基本上有两个主要策略:
- 默认 export/import
export default
和 import module from './module'
- Multiple exports/imports with
export
and import {member} from './module'
or import * as module from './module'
(可以混合使用,但不推荐。)
模块到 export/import
function foo() {
console.log('Foo');
}
function bar() {
console.log('Bar');
}
策略#1:默认export/import
导出 (module.js)
function foo() {
console.log('Foo');
}
function bar() {
console.log('Bar');
}
export default {foo, bar};
/*
{foo, bar} is just an ES6 object literal that could be written like so:
export default {
foo: foo,
bar: bar
};
It is the legacy of the "Revealing Module pattern"...
*/
导入 (main.js)
import module from './module';
module.foo(); // Foo
module.bar(); // Bar
策略#2:多个exports/imports
导出 (module.js)
export function foo() {
console.log('Foo');
}
export function bar() {
console.log('Bar');
}
导入 (main.js)
import {foo, bar} from './module';
foo(); // Foo
bar(); // Bar
/*
This is valid too:
import * as module from './module';
module.foo(); // Foo
module.bar(); // Bar
*/
正如我之前所说,ES6 模块比这复杂得多。有关更多信息,我建议您阅读 Dr. Exploring ES6。 Axel Rauschmayer,尤其是这一章:http://exploringjs.com/es6/ch_modules.html.
在你的例子中,如果你从 src/web-api.js
文件导入而不带大括号,你应该在 src/webfile-api.js
中有一个 export default something
没有花括号
class WebApi {...};
export default WebApi;
在你的文件中
import WebApi from './src/web-api.js'
// 此处,src/web-api.js
文件中带有export default
的元素应在任何地方不带花括号的情况下导入。
PS:每个文件必须只有一个export default
。
带花括号
export { WebApi }
在你的文件中
import {WebApi} from './src/web-api.js'
Dan Abramov 在这个答案中清楚地解释了 ES6 中的 export/import
方法。
我是 ES6 的新手,对 classes 的导出和导入方式有点困惑。似乎许多不同的符号都是有效的,但工作方式不同。
我在src/web-api.js
中写了一个这样的class:
class WebApi {
// ...
}
export { WebApi };
我导入的是:
import { WebApi } from './src/web-api.js'
这工作正常,但在我尝试没有大括号的同样的事情之前它没有工作:
export WebApi; // Tells me '{' expected
import WebApi from './src/web-api.js'; // No syntax error but WebApi is undefined
即使在 MDN documentation for export 上,符号 export expression;
似乎是有效的。
同样,这是在我的应用程序文件中导入 React 的方式:
import React, { Component } from 'react';
为什么一个 class 有大括号,另一个没有大括号?一般来说,我怎么知道什么时候使用和不使用大括号?
大括号只是语法糖。它将使用变量名作为对象键,例如:
const a = 1;
const test = {a}; // same as {a: 1};
它也可以用来通过变量名来解构对象。它将检查对象是否具有与变量名具有相同值的属性,如果找到则输出一个值:
const test = {a: 1};
const {a} = test; // a = 1
在模块中,一般用例是当您导入时通常有大括号,因为模块被导入为 MODULE.function
或 MODULE.class
。先看exports会更直观:
对于导出,它使用了我之前提到的语法糖 - 您将其作为对象导出。当你做 export { WebApi };
时,你真正在做的是 export {WebApi: WebApi}
。这使得访问内容变得更容易,因为您现在可以 'MODULE.WebApi' 访问 class 而不是让它不必要地污染命名空间。这也是所有导出所必需的!
继续导入,您在导入语句中所做的实质上是解构模块对象并选择 属性 保存到同名变量中。在您的情况下,当您执行 import {WebApi} from './src/web-api.js'
时,您会执行类似 import WebApi = web-api.js['WebApi'] from './src/web-api.js'
的操作(这不是有效的语法,只是为了向您展示它在后台执行的操作)。这也是正确导入模块 functions/classes 所必需的。还有一个导入整个模块的选项,就像 NodeJS 一样:import * as ModuleName from './src/module.js'
。这会将所有导出的 functions/classes 放入 ModuleName 对象中,以便将其视为普通模块。
但是,如果模块具有 default
导出,则导入和导出不需要大括号。例如,React 的文件中可能有 export default React
- 这就是为什么当你做 import React from 'react'
希望我没有太混乱,如果我能澄清任何事情,请告诉我!
ES6 提供了多种 方式来通过import/export 管理模块。但基本上有两个主要策略:
- 默认 export/import
export default
和import module from './module'
- Multiple exports/imports with
export
andimport {member} from './module'
orimport * as module from './module'
(可以混合使用,但不推荐。)
模块到 export/import
function foo() {
console.log('Foo');
}
function bar() {
console.log('Bar');
}
策略#1:默认export/import
导出 (module.js)
function foo() {
console.log('Foo');
}
function bar() {
console.log('Bar');
}
export default {foo, bar};
/*
{foo, bar} is just an ES6 object literal that could be written like so:
export default {
foo: foo,
bar: bar
};
It is the legacy of the "Revealing Module pattern"...
*/
导入 (main.js)
import module from './module';
module.foo(); // Foo
module.bar(); // Bar
策略#2:多个exports/imports
导出 (module.js)
export function foo() {
console.log('Foo');
}
export function bar() {
console.log('Bar');
}
导入 (main.js)
import {foo, bar} from './module';
foo(); // Foo
bar(); // Bar
/*
This is valid too:
import * as module from './module';
module.foo(); // Foo
module.bar(); // Bar
*/
正如我之前所说,ES6 模块比这复杂得多。有关更多信息,我建议您阅读 Dr. Exploring ES6。 Axel Rauschmayer,尤其是这一章:http://exploringjs.com/es6/ch_modules.html.
在你的例子中,如果你从 src/web-api.js
文件导入而不带大括号,你应该在 src/webfile-api.js
export default something
没有花括号
class WebApi {...};
export default WebApi;
在你的文件中
import WebApi from './src/web-api.js'
// 此处,src/web-api.js
文件中带有export default
的元素应在任何地方不带花括号的情况下导入。
PS:每个文件必须只有一个export default
。
带花括号
export { WebApi }
在你的文件中
import {WebApi} from './src/web-api.js'
Dan Abramov 在这个答案中清楚地解释了 ES6 中的 export/import
方法。