我试图确定这两者之间是否有任何重大差异,除了能够通过以下方式导入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
是一个命名的导出,它导出一个或多个 const 声明。
强调一下:这里重要的是export
关键字 asconst
用于声明一个或多个 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
: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
当{}
语法用于导入函数(或变量)时,这意味着导入的任何内容在导出时都已命名,因此必须以完全相同的名称导入它,否则导入将不起作用。
默认函数必须先导入
import {divide}, square from './module_1.js
divide_1
未导出module_1.js
,因此不会导入任何内容
import {divide_1} from './module_1.js
square
未在 中导出module_1.js
,因为{}
告诉引擎仅显式搜索命名导出。
import {square} from './module_1.js
次要注意:请考虑从默认导出导入时,命名是完全独立的。这实际上对重构有影响。
假设您有一个这样的类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'
更重要的区别是:export default
exports value,而export const
// exports reference(export var
或者export let
被称为live binding)。在 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 ./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
声明,即default
.
webpack 有类似的构建输出。当添加大量模块构建时,拼接文本是不可持续的,捆绑器将用于
Object.defineProperty
实现绑定(或在 webpack 中称为和谐导出)。请在下面的代码中找到详细信息:
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 模块的原因、内容和方式。
从文档中:
命名导出对于导出多个值很有用。在导入期间,可以使用相同的名称来引用相应的值。
关于默认导出,每个模块只有一个默认导出。默认导出可以是函数、类、对象或其他任何东西。该值将被视为“主要”导出值,因为它将是最简单的导入值。
当您设置默认值时,它称为默认导出。每个文件只能有一个默认导出,您可以将其导入另一个文件,使用任何您想要的名称。当您不设置默认值时,它称为命名导出,您必须将其导入到另一个文件中,使用相同的名称并在其中包含花括号。
我遇到了浏览器不使用ES6的问题。
我已经修复它:
<script type="module" src="index.js"></script>
type 模块告诉浏览器使用 ES6。
export const bla = [1,2,3];
import {bla} from './example.js';
然后它应该工作。