ES6
Promise
- 手写Promise
- 核心逻辑在Promise.then方法需要考虑参数不同类型的情况
- 执行resolve或者reject时需要判断状态
- 通过两个函数队列来实现链式调用时的自执行
- 通过setTimeout来模拟微任务
- 手写Promise.all
- 返回一个Promise
- 使用单独的计数变量来判断什么时候resolve
- Promise的方法和属性
- 三个状态:pending、fullfilled、rejected
- then、resolve、reject、all、race、allSettled、finally
- 状态只能从pending变成fullfilled或者rejected,一旦变更后无法再修改状态
- generator函数的用法
- function* 来声明函数,在函数内部使用 yield 来处理异步
- generator函数返回值为一个可迭代的函数
- 调用返回函数的 next 方法,得到 {value: any; done: boolean} 类型返回值
- 继续调用 next 方法,直到最后一个值返回后,done变为 true
- 可以通过 [...generator()] 快速获得返回函数的执行结果
- async await 的用法和原理
- generator函数的语法糖
- try catch 捕获异常
- generator函数要多次调用,async方法只需要调一次
- 自执行的generator函数,可递归或者循环实现
数组
- concat:合并数组并返回新数组,不改变原数组
- entries:返回数组的迭代器(类似于generator的返回)
- every:检查数组中的每一项是否符合条件
- some:检查数组中是否存在某一项符合条件
- flatMap:相当于先调map,再调flat(1)
- Array.from:通过浅拷贝的方式生成数组
- pop:删除并返回最后一个元素,改变原数组
- push:添加一个元素并返回新数组的长度
- shift:删除第一个元素并返回该元素,与pop对应
- unshift:在数组头部添加一个元素并返回新数组的长度,与push对应
- sort:正数升序、负数降序,会改变原数组,不想改变原数组可以使用 toSorted 方法
装饰器
- 作用于Class类,类的属性以及方法上
- 接收三个参数:对象、属性名称、属性描述符(属性描述符通常用于传递给Object.defineProperty)
- 类似于高阶函数,简化了调用方式,相当于一种语法糖
- 使用例子:在装饰器中通过类继承的方式来增强类、修改方法的属性描述符的值来修改方法等
Proxy
- 代理对象,通过 new Proxy(target, handler) 的方式来实现代理
- handler为包含一系列对象操作方法的对象,如 get、set、has、defineProperty等
Map和Set
- Map的key可以为任意值,且key值始终唯一
- Map的键值对顺序跟插入顺序保持一致
- Map的方法:get、set、delete、clear、has 等
- Set中的每一项可以是任意类型,且不会重复
- new Set([]) 参数为数组,返回类数组对象
Class
- 支持 getter 和 setter
- 通过 static 关键字,或者 Class.xxxx 定义静态变量和方法
- Class 的实例化与 new 关键字的逻辑相同
- Class的继承
- 首先将子类的原型替换为父类的原型
- 然后需要将子类原型的构造函数再设置为子类的构造函数
- 最后只需要将父类上的静态方法和属性添加给子类即可
箭头函数
- 没有this、arguements等,它的this来源于当前作用域的上一层内this
- 箭头函数可以使用call和apply,但是会忽略第一个参数
- 箭头函数不能作为构造函数,且没有原型对象
模板字符串
- String.raw 用于获取原生字符串(不会做任何转义)
解构赋值
- 用于快速从数组或对象中获得想要的数据
- [a, b] = [b, a] 用来快速交换值
- const [a, , b] = [1, 2, 3] 用于忽略不想要的值
- 在结构对象时,会去查找原型链上的属性和方法
let和const
- 不会进行变量提升,在变量声明之前调用都会报错
- 提供了块级作用域,在一个块内的变量都是单独的
- let可以修改,const不能修改,但是 const 的引用类型可以修改引用的值
模块化
- CommonJS
- NodeJS中采用的模块化方式,通过require导入,exports和module.exports导出
- module.exports = { xxx } 相当于 exports.xxx,不能混用
- 使用require导入时,若导入模块未执行则会先执行,已经执行过的则直接导入
- requirejs导入的为对象的值,因此修改导入的对象不会改变原对象
- require支持动态导入,但是同步加载,只有导入的模块代码执行完成才能成功导入
- ES Module
- 通过 export、export default 导出,import 导入,导出时 export 和 export default 可以同时使用
- export * from 、export {default as xxx} from 、export {xxx} from
- 支持 import(xxx).then 的方式动态导入
- export 具名导出时导出的是引用地址,export default 导出时与其他模块化一样是复制值
- 浏览器通过 script 标签中的 type="module" 使用,NodeJS中通过 package.json 中的 type: module 使用
- AMD/CMD/UMD
- AMD主要解决了CommonJS无法异步导入的问题,通过define定义模块,通过require和回调的方式导入模块
- AMD模块在浏览器端可以通过RequireJS实现,也支持按需和动态导入
- CMD的逻辑与AMD模块方式相同,只是在实现上支持按照CommonJS的语法去使用,define(function(require, exports, module) {})
- CMD可以通过seajs去实现
- UMD则是一种同时兼容AMD、CMD与CommonJS的方式,每一个模块都由一个自执行函数包裹,在自执行的函数中通过判断 module、define 等关键字实现兼容处理
Ajax ,Fetch,Axios
- Ajax 全称是 异步JavaScript和XML。最传统的页面如果需要更新内容,需要重载整个页面,Ajax无需加载整个网页的情况下,能够更新部分网页数据。 针对MVC编程,不符合MVVM的浪潮;基于原生的xhr开发,xhr本身架构部清晰;配置调用方式混乱,对异步调用不友好。
- fetch不是基于ajax的,是原生的es6,基于promise设计的,代码结构简单易用,fetch只针对网络请求报错,如对500错误码也当请求成功。默认不携带cookie,需额外配置。
- Axios,基于promise的封装,浏览器端发起XMLHttpRequest请求,node端发起http请求。可以监听请求进度,支持取消请求(AbortController)。