ES Module 学习

ES Module 学习,第1张

ES Module 学习 ES Module 学习

ES Module 使用 import 和 export 关键字。

export 负责模块的内容导出import 负责从其他模块导入内容注:将ES Module 的 export、import 关键字 与 Common JS 的Module.exports、exports、require 对象区分开。 采用编译器的静态分析,亦加入了动态引用的方式采用 ES Module 将自动采用严格模式:use strict ES Module 常见导出方式

const name = "huaqi";
const age = 18;
const sayHello = function (name) {
  console.log("Hello" + name);
};

// 第一种导出方式,声明式 前添加 export 关键字
export const name = "huaqi";
export const age = 18;
export const sayHello = function (name) {
  console.log("Hello" + name);
};

// 第二种导出方式,{ } 中统一导出
// 此时 { } 并不是声明一个对象
// { 放置待导出的变量的引用列表 } (变量在此处不严谨)
export {
   nanme, 
   age, 
   sayHello 
   };

// 第三种导出方式,{ } 中另起别名统一导出
export { 
  name as huaqiName, 
  age as huaqiAge, 
  sayHello as huaqiSayHello 
  };

ES Module 常见导入方式
// 第一种导入方式, 这里的 {} 仍不是声明对象
// 注:由于 JS 引擎本身并没有类似 Node、WebPack 的文件查找机制,文件名后必须添加 js 后缀
import { name, age, sayHello } from "./huaqi.js";

// 第二种导入方式, {} 起别名
import { name as huaName, age as huaAge, sayHello as huaSayHello} from './huaqi.js';

// 第三种导入方式, * as hua, 将所有导入到内容作为对象 hua 的属性
import * as hua from './huaqi.js';
hua.name;
hua.age;
hua.sayHello();

export 与 import 结合使用

相当于一个中转站,将导入的内容直接导出。
应用场景:可将所有 API 集合到统一文件,方便管理与使用。

export { name. age. sayHello } from "./huaqi.js";
export default 用法

上述举例的导出均为具名导出(named exports),即

在导出内容时指定了名字在导入时,根据名字导入相应内容

另外一种导出称为默认导出(default exports)

默认导出可以不指定名字在导入时不需要使用 { },并且可以自定义名称方便与现有的 CommonJS 等规范相互 *** 作

注:在一个模块中,只能有一个默认导出(default export)

代码示例:

// huaqi.js
export default function () {
  console.log("default export");
}

------------------------------

// huahua.js
import name from "huaqi.js";
name();

import() 函数

通过 import 关键字引入内容时,不能将其声明于逻辑代码中,比如:

// 不能使用以下方式引入内容
if (true){
    import sub from './modules/sub.js';  
} 

JS 引擎解析代码中的 ES Module 时,必须明确其依赖解析过程中,JS 代码并没有执行,即无法进行类似 if 判断,更不能明确其中的依赖关系

当确实需要动态引入某一模块时,可以使用 import() 函数以动态引入模块

import() 作为函数,在代码执行阶段运行, 并不需要明确其依赖关系import() 函数返回一个 promise 对象

即支持如下代码:

let flag = true;
if (flag) {
    import('./modules/aaa.js').then(aaa => {
        aaa.aaa();
    })
} else {
    import('./module/bbb.js').then(bbb => {
        bbb.bbb();
    })
}

当然在支持 Common JS 规范的情况下,可以随便使用 require() 函数引入内容,原理与 import() 函数相同。

CommonJS 导出与引入过程

CommonJS 模块引入 JS 文件是在运行时引入的,并且是同步的。

运行时引入:JS 引擎在执行 JS 代码的过程中引入模块。同步:一个模块在没有引入(第一此引入模块时,模块会自执行一次)结束之前,之后的代码都不会执行

CommonJS 通过 moudule.exports 导出对象。

导出对象,意味着可以将该对象的引用在其他模块中赋值给其他变量默认情况下,导出与引入该对象的模块指向的都是同一个对象,任一一个模块都可修改对象中的属性值。 ES Module 导出导入过程

ES Module 在 JS 解析/编译 过程中异步导入内容。

解析/编译 时加载: import 关键字不能与运行时相关内容一起使用

import … form 路径不能为动态获取不能将 import … from 语句置于逻辑代码中故称 ES Module 为静态解析 异步引入:JS 引擎在遇到 import 关键字时会执行该语句,由于是异步过程,所以并不会阻塞主线程继续执行

script 元素若使用 type=“module” 属性,相当于添加了 async 属性

ES Module 在导出内容时,会维护一个模块环境记录内存空间(module environment record),该空间内会对导出模块对于导出内容做实时绑定(bindings)例如:

// step01
// 导出模块内 huaqi.js
let name = "huaqi";
export { name };

// MER 空间内
const name = nameReference01; // 将导出模块的 name 变量的引用赋值给空间内 name 变量

// 导入模块内 huahua.js
import { name } from "huaqi.js"; // 导入模块内的 name 可以认为是空间内 name 变量
// 由于空间内变量由 const 定义,故在导入模块内不能改写变量 name 


// step02
// 导出模块内 huaqi.js
let name = "huahua"; 

// MER 空间内
const name = nameReference02; // 此时会将导出模块的 name 变量的引用重新赋值给空间内新的 name 变量,原空间内变量 name 消失
// 所以在导出模块内,可以改写变量 name

// step03
// 导出模块内 huaqi.js
let name = {
    name: "huaqi";
}

// MER 空间内
const name = nameReference03; // 此时的 nameReference03 即是对象 {name: "huaqi"} 的地址,进而 name 保存的亦是 该对象的地址
// 导出模块与导入模块均可通过该地址修改对象中属性

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5711281.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存