CommonJS、AMD、CMD 和 ESM

一、Common JS

  1. CommonJS 它是通过 require 来引入模块,通过 module.exports 定义模块的输出接口。这种模块加载方案是服务端的解决方案,它是以同步的方式来引入模块的。(因为服务端的文件都存储在本地磁盘,所以读取起来非常快,用同步的方式没有问题,但在浏览器端,由于模块加载是使用网络请求的,所以使用 异步的方式更合适)
  2. CommonJS 输出的是一个只的拷贝,会有缓存,这个值一旦输出,模块内部更新, 对于输出的这个值不会有影响
  3. CommonJS 是在运行时加载的,CommonJS 模块是个对象,输入时会先加载一整个模块生成一个对象,从这个对象上取值

二、AMD

  1. AMD 采用 异步方式来加载模块的,模块的加载不影响后面语句的执行,所有依赖这个模块的语句都定义在一个回调函数里,等到加载完成再去执行回调函数。require.js 实现了 AMD 规范

  2. AMD 在使用模块依赖时,必须先声明依赖,并且依赖模块加载完成就立即执行,依赖模块的顺序可能和我们书写的并不一致

三、CMD

  1. CMD 和 AMD 一样都是为了解决异步模块加载问题。它和 AMD 的区别在于 模块定义时对依赖的处理不同 和依赖模块的执行时机处理不同。
  2. CMD 模块依赖可以就近声明,使用时再去声明
  3. CMD 会先将模块依赖下好,等待代码执行时再去执行,所以模块依赖执行顺序和我们书写的顺序一致。

ESM

  1. ESM 是 ES6 提出的方案,使用 import 和 export 的形式来导入导出模块。

  2. ESM 输出的是一个值的引用,即模块内部值更新,所有引用该值的地方都会更新

  3. ESM 是在代码解析时生成的,采用静态优化 是静态执行的,因此不能有变量、表达式等这些只有在代码运行时才能得到结果写法。

  4. ESM 对外输出的是一个接口,必须和模块内部建议一对一的关系。

5 ESM import 输入的变量都是只读的,并且import 会有提升效果,提升到首部提前执行

  1. ESM import 多个重复语句,只会执行一次。

手写Promise

什么是Promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const PENDING = 'pending'
const REJECTED = 'rejected'
const FULFILLED = 'fulfilled'

class Promise {
constructor(executor) {
this.status = PENDING
this.value = undefined
this.reason = undefined

this.onResolveCallbacks = []
this.onRejectCallbacks = []

let resolve = (value) => {
if(this.status === PENDING) {
this.status = FULFILLED
this.value = value

this.onResolveCallbacks.forEach(fn => fn())
}
}

let reject = (reason) => {
if(this.status === PENDING) {
this.status = REJECTED
this.reason = reason

this.onRejectCallbacks.forEach(fn => fn())
}
}

try{
executor(resolve, reject)
} catch(err) {
reject(err)
}
}

then(onFulfilled, onRejected) {
if (this.status === FULFILLED) {
onFulfilled(this.value)
}
if (this.status === REJECTED) {
onRejected(this.reason)
}

if (this.status === PENDING) {
this.onResolveCallbacks.push(() => onFulfilled(this.value))

this.onRejectCallbacks.push(()=> onRejected(this.reason))
}
}
}

Symbol

Symbol 表示一个独一无二的值,它引入的原因是 由于 ES5 的对象属性都是字符串,我们再去使用别人提供的对象时,如果要在这个对象上添加属于 有可能会有属性冲突, 如果对象中的每个值都是独一无二的,那么就没有这种问题了,于是引入了 Symbol

Symbol 是原始数据类型中独一无二的值, js 一共有五种基本数据类型,分别是 Undefined、Null、Boolean、Number、String,还有在 ES6 中新增的 Symbol 和 ES10 中新增的 BigInt 类型。
Symbol 代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突的问题。
BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。

cookie、sessionStorage、localStorage 的区别

这三种 都是浏览器存储信息的一种手段, 共同点:都是保存在浏览器端,且是同源的

  1. cookie:

    • 存储容量限制,一般是在 几 kb (4kb\5kb)
    • cookie 可以设置具体的过期时间,可以是会话级(浏览器关闭时失效)或者具体的过期日期
    • cookie 用于客户端和服务器之间传输,每次请求都会被发送到服务器端,因此对于跨域请求和安全性有一定的限制
    • 可以通过设置域名路径来控制 cookie 的作用域,实现跨子域和跨路径的共享
  2. Session Storage

    • 存储容量可以达几M,5M左右,但是会话级别的,浏览器一关闭 就自动清除
    • 它只存储在客户端,每次请求不会被发送到服务器端
    • 仅限于当前源,不同页面间不能共享数据
  3. localStorage

    • 存储容量比 sessionStorage 更大,且数据可以长期保存
    • 可以持久化存储数据,关闭浏览器会话不会数据被清除
    • 仅限于当前源,不同页面间不能共享数据