Skip to content

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

  1. Ajax 全称是 异步JavaScript和XML。最传统的页面如果需要更新内容,需要重载整个页面,Ajax无需加载整个网页的情况下,能够更新部分网页数据。 针对MVC编程,不符合MVVM的浪潮;基于原生的xhr开发,xhr本身架构部清晰;配置调用方式混乱,对异步调用不友好。
  2. fetch不是基于ajax的,是原生的es6,基于promise设计的,代码结构简单易用,fetch只针对网络请求报错,如对500错误码也当请求成功。默认不携带cookie,需额外配置。
  3. Axios,基于promise的封装,浏览器端发起XMLHttpRequest请求,node端发起http请求。可以监听请求进度,支持取消请求(AbortController)。