ES 模块用于在浏览器环境和服务器环境中使用。
模块就是以 .js
为扩展名的 JavaScript 文件。
普通脚本文件内的顶级的成员对其它脚本文件来说是公开(public)的全局上下文,而模块文件内的顶级的模块成员对其它模块文件来说都是私有(private)的,所以首先需要在模块中将它们显式导出,然后在其它模块中显式导入它们才可以使用。
1.导出(export)
同一个模块中可同时存在命名导出和默认导出,但是为了减少命名导出和默认导出之间潜在的混淆,一些团队选择在整个项目中只坚持使用命名导出和默认导出中的其中一种,或者在整个项目中使用命名导出和默认导出两种但避免在同一个模块中混合使用它们。
注意:export
语句必须位于模块文件内的顶级。
1.1命名导出(named export)一个对象字面量
命名导出的值为一个对象字面量,对象字面量的属性则为需要导出的模块成员。
注意:实际上,导出的值不是一个对象字面量,在这里为了易于理解,暂且理解为一个对象字面量。
//前缀方式
//类声明
export class 类名 {
//类体
}
//命名类表达式
export {let | const} 类名 = class 类名2 {
//类体
};
//匿名类表达式
export {let | const} 类名 = class {
//类体
};
//变量
export let 变量名;
export let 变量名 = 值;
//常量
export const 常量名 = 值;
//函数声明
export function 函数名(形参) {
//函数体
}
//命名函数表达式
export {let | const} 函数名 = function 函数名2(形参) {
//函数体
};
//匿名函数表达式
export {let | const} 函数名 = function (形参) {
//函数体
};
//箭头函数表达式
export {let | const} 函数名 = (形参) => {
//函数体
};
//注意:不支持此语法。
export 字面量;
//末尾方式
//类声明
class 类名 {
//类体
}
//命名类表达式
{let | const} 类名 = class 类名2 {
//类体
};
//匿名类表达式
{let | const} 类名 = class {
//类体
};
//变量
let 变量名;
let 变量名 = 值;
//常量
const 常量名 = 值;
//函数声明
function 函数名(形参) {
//函数体
}
//命名函数表达式
{let | const} 函数名 = function 函数名2(形参) {
//函数体
};
//匿名函数表达式
{let | const} 函数名 = function (形参) {
//函数体
};
//箭头函数表达式
{let | const} 函数名 = (形参) => {
//函数体
};
//导出
export { 类名, 变量名, 常量名, 函数名 };
export { 类名 as 类别名, 变量名 as 变量别名, 常量名 as 常量别名, 函数名 as 函数别名 };
//注意:不支持这两个语法。
export { 字面量 };
export { 字面量 as 别名 };
1.2默认导出(default export)一个模块成员
默认导出的值为一个模块成员。
注意:因为 default
是别名,所以一个模块中只能有一个 export default
,不然会发生别名冲突。
//前缀方式
//命名类表达式
export default class 类名 {
//类体
}
//匿名类表达式
export default class {
//类体
}
//注意:不支持这三个语法。
export default let 变量名;
export default let 变量名 = 值;
export default const 常量名 = 值;
//命名函数表达式
export default function 函数名(形参) {
//函数体
}
//匿名函数表达式
export default function (形参) {
//函数体
}
//箭头函数表达式
export default (形参) => {
//函数体
}
//字面量
export default 字面量;
//末尾方式
//类声明
class 类名 {
//类体
}
//命名类表达式
{let | const} 类名 = class 类名2 {
//类体
};
//匿名类表达式
{let | const} 类名 = class {
//类体
};
//变量
let 变量名;
let 变量名 = 值;
//常量
const 常量名 = 值;
//函数声明
function 函数名(形参) {
//函数体
}
//命名函数表达式
{let | const} 函数名 = function 函数名2(形参) {
//函数体
};
//匿名函数表达式
{let | const} 函数名 = function (形参) {
//函数体
};
//箭头函数表达式
{let | const} 函数名 = (形参) => {
//函数体
};
//导出
export { 类名 as default };
export { 变量名 as default };
export { 常量名 as default };
export { 函数名 as default };
//注意:不支持这两个语法。
export { 字面量 as default };
export { (new 类名()) as default };
//简写
export default 类名;
export default 变量名;
export default 常量名;
export default 函数名;
export default 字面量;
export default new 类名();
2.导入(import)
import ... from '模块标识符'
import '模块标识符'
//模块标识符格式
//绝对路径
from '/module.js'
//相对路径
from './module.js'
from '../module.js'
//Node.js内置模块
from 'node:module'
//npm包(目录)内模块
from '包名'
注意:import
语句必须位于模块文件内的顶级。
注意:import
语句非必须位于模块文件内的顶部 ,但推荐将 import
语句放置在模块文件内的顶部。
注意:另一个模块无论在同一个模块中导入多少次,实际上只会被导入一次。
2.1命名导入(named import)一个对象字面量
注意:实际上,使用的不是解构赋值语法,在这里为了易于理解,暂且理解为解构赋值语法。
//命名导出对应的导入方式
//方式一(直接将对象字面量赋值给别名)
//注意:如果模块标识符同时存在命名导出和默认导出,则*会同时导入命名导出和默认导出的模块成员。
import * as 别名 from '模块标识符';
//注意:不支持此语法。
import * from '模块标识符';
//方式二(使用解构赋值只导入打算使用的模块成员)
import { 类名, 变量名, 常量名, 函数名 } from '模块标识符';
import { 类名 as 类别名, 变量名 as 变量别名, 常量名 as 常量别名, 函数名 as 函数别名 } from '模块标识符';
2.2默认导入(default import)一个模块成员
//默认导出对应的导入方式
//方式一(使用解构赋值导入模块成员)
import { default as 别名 } from '模块标识符';
//方式二(直接将模块成员赋值给import后的标识符,标识符非必须与默认导出的模块成员名相同)
import 类名 from '模块标识符';
import 变量名 from '模块标识符';
import 常量名 from '模块标识符';
import 函数名 from '模块标识符';
2.3导入模块运行的结果
import '模块标识符'
无论 '模块标识符'
有没有模块成员的导出,并不会导入任何模块成员,而是将模块运行的结果作为另一个模块的一部分,而不是将模块内的代码作为另一个模块的一部分。
3.再导出(re-export)
导入的模块成员可以在模块内不被使用而直接再导出。
再导出相当于先 import ... from '模块标识符'
语句后 export
语句合二为一的语法糖。
注意:作为再导出的模块成员不可以在此模块中被使用。
//命名导入再命名导出
//注意:如果模块标识符同时存在命名导出和默认导出,则*只会导入命名导出的模块成员,而不会导入默认导出的模块成员。
export * from '模块标识符';
export * as 别名 from '模块标识符';
export { 模块成员名 } from '模块标识符';
export { 模块成员名 as 模块成员别名 } from '模块标识符';
//命名导入再默认导出
export { 模块成员名 as default } from '模块标识符';
//默认导入再命名导出
export { default as 别名 } from '模块标识符';
//默认导入再默认导出
export { default } from '模块标识符';
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/javascript/javascriptlang/3556.html