我正在尝试确定这两者之间是否存在任何大的区别,除了可以通过以下方式使用export default
导入:
import myItem from 'myItem';
并且使用export const
,我可以这样做:
import { myItem } from 'myItem';
除此之外,还有什么区别和/或使用情况吗?
我正在尝试确定这两者之间是否存在任何大的区别,除了可以通过以下方式使用export default
导入:
import myItem from 'myItem';
并且使用export const
,我可以这样做:
import { myItem } from 'myItem';
除此之外,还有什么区别和/或使用情况吗?
这是一个具名导出与默认导出的区别。export const
是一种具名导出方式,用于导出一个或多个常量声明。
需要强调的是:关键字 export
很重要,因为 const
用于声明一个或多个常量声明。而 export
还可以应用于其他声明,比如类或函数声明。
默认导出 (export default
)
每个文件只能有一个默认导出。当你导入时,必须指定名称并像这样导入:
import MyDefaultExport from "./MyFileWithADefaultExport";
你可以给它任何你喜欢的名字。
命名导出(export
)
通过命名导出,你可以在一个文件中拥有多个命名导出。然后在大括号内导入你想要的特定导出:
// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";
// use MyClass, MyOtherClass, and MyClass2Alias here
或者在同一条语句中使用默认导出和命名导入:
import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";
命名空间导入
从一个对象中导入文件的所有内容也是可能的:
import * as MyClasses from "./MyClass";
// use MyClasses.MyClass, MyClasses.MyOtherClass and MyClasses.default here
注意事项
默认导出实际上是一个具有名称为default
的命名导出,因此您可以使用命名导入来导入它:
import { default as MyDefaultExport } from "./MyFileWithADefaultExport";
export default
会影响导入所需的语法,允许通过在 import
中选择名称来导入任何已经被导出的东西,无论它在导出时使用的名称是什么,只要它被标记为 "default"。一个有用的用例是可以导出一个匿名函数,而不必显式地为其命名,只有在导入该函数时,才需要为其赋予一个名称:
default
:export function divide( x ){
return x / 2;
}
// only one 'default' function may be exported and the rest (above) must be named
export default function( x ){ // <---- declared as a default function
return x * x;
}
default
函数起一个名称:// The default function should be the first to import (and named whatever)
import square, {divide} from './module_1.js'; // I named the default "square"
console.log( square(2), divide(2) ); // 4, 1
使用 {}
语法导入函数(或变量)时,它意味着无论导出内容如何命名,导入时必须使用完全相同的名称,否则导入将不起作用。
The default function must be first to import
import {divide}, square from './module_1.js
divide_1
was not exported in module_1.js
, thus nothing will be imported
import {divide_1} from './module_1.js
square
was not exported in module_1.js
, because {}
tells the engine to explicitly search for named exports only.
import {square} from './module_1.js
import something from
而不是 import { somethingNamed } from
。 - Andris更重要的区别是:export default
导出值,而export const
/export var
/export let
导出引用(也被称为活绑定)。在nodejs中尝试下面的代码(使用13或以上版本以默认启用es模块):
// a.mjs
export let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
export default x;
// index.mjs
import y, { x } from './1.mjs';
setInterval(() => {
console.log(y, x);
}, 1000);
# install node 13 or above
node ./index.mjs
我们应该得到以下输出:
6 5
7 5
8 5
...
...
很可能,export default
是为了与 commonjs 的 module.exports
兼容而使用的。
对于上述代码,我们使用 rollup 进行打包。
rollup ./index.mjs --dir build
生成的输出为:
// build/index.js
let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
var y = x;
setInterval(() => {
console.log(y, x);
}, 1000);
请注意
var y = x
语句,这是默认设置。
webpack具有类似的构建输出。当大量模块添加到构建中时,连接文本是不可持续的,打包工具将使用
Object.defineProperty
来实现绑定(或在webpack中称为"harmony exports")。请在下面的代码中查找详细信息:
main.js
...
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
...
// 1.js
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],[
/* 0 */,
/* 1 */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "x", function() { return x; });
let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
/* harmony default export */ __webpack_exports__["default"] = (x);
/***/ })
]]);
请查找
/* harmony export (binding) */
和/* harmony default export */
之间的不同行为。
Mozilla的es-modules-a-cartoon-deep-dive介绍了关于ES模块的为什么、什么以及如何。
小提示:请记住,当您从默认导出中导入时,名称是完全独立的。这实际上会影响重构。
假设您有一个类Foo
,并对应有一个导入:
export default class Foo { }
// The name 'Foo' could be anything, since it's just an
// Identifier for the default export
import Foo from './Foo'
如果你对Foo
类进行重构,改名为Bar
并且重命名文件,大多数IDE将不会修改你的导入语句。因此,你最终会得到以下结果:
export default class Bar { }
// The name 'Foo' could be anything, since it's just an
// Identifier for the default export.
import Foo from './Bar'
特别是在TypeScript中,我非常赞赏命名导出和更可靠的重构。区别仅在于缺少default
关键字和花括号。顺便提一下,现在由于有类型检查,这也可以防止你在导入时犯错。
export class Foo { }
//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'
import { Foo as Anything } from …
,也可以使用import Anything from …
。 - Bergias
重命名它,但这并不是源代码注释的重点。感谢你的投票;p - Philipp Sumiexport default
来导出一个项目的主要对象,特别是从 npm 包中(它代替了 module.exports =
)。但在项目内部,最好仅使用命名导出。 - Paleo来自文档:
命名导出非常有用,可用于导出多个值。在导入期间,可以使用相同的名称引用相应的值。
关于默认导出,每个模块只有一个默认导出。默认导出可以是函数、类、对象或其他任何值,此值应被视为“主”导出值,因为它最简单易懂。
当你使用default时,它被称为默认导出。每个文件只能有一个默认导出,并且您可以使用任何名称在另一个文件中导入它。当您不使用default时,它被称为命名导出,您必须在另一个文件中使用相同的名称和花括号导入它。
const
将使标识符只读。因此,在原始值的情况下,您可以将其视为不可变。请注意,值本身并非不可变,因此对象、数组等可以更改,但不能重新分配。 - spmurrayzzzconst
一样是不可变的。 - Felix Kling