手写bind、深拷贝、EventHub、Promise。
手写bind
定义
bind用法不难,就是把新的this绑定到某个函数func上,并返回func的一个拷贝。
用法
function.bind(thisArg[, arg1[, arg2[, …]]])
功能点
- 改变原函数的this指向,即绑定上下文,返回原函数的拷贝
- 当绑定函数被调用时,bind的额外参数将置于实参之前传递给被绑定的方法
- 注意,一个 绑定函数 也能使用 new 操作符创建对象,这种行为就像把原函数当成构造器,thisArg 参数无效。也就是 new 操作符修改 this 指向的优先级更高。
实现
只使用ES6语法
- 优点:因为可以使用 const 、… 操作符,代码简洁
- 缺点:兼容性稍差,不能兼容IE等古老浏览器。
1 | function myBind(thisArg, ...args) { |
兼容IE
1 | Function.prototype.myBind = function (thisArg) { |
new关键字
1 | Function.prototype.myBind2 = function(thisArg) { |
手写深拷贝
释义
- 为什么要深拷贝? 不希望数据被修改或数据只需要部分修改
- 如何实现深拷贝? 简单需求用JSON反序列化,复杂需求用递归克隆
JSON反序列化
1 | var obj = { |
缺点
- JSON value不支持的类型,都拷贝不了。
- undefined、函数、循环引用、正则等都不支持。
递归克隆
核心
- 对象分类
- 递归
- 用缓存对付环
1 | function deepClone(source, wm = new WeakMap()) { |
延伸: 深拷贝与浅拷贝的区别
浅拷贝: 只复制一层对象的属性,复制出来的数据,指向的数据内存地址是一样的,修改任意一个都会使复制出的数据同样发生变化。
浅拷贝: 不仅复制原对象的属性,还会将原对象属性所包含的对象也依次采用深复制的方法递归复制到新的对象上。
手写EventHub(发布订阅)
核心
- on 发布监听
- emit 负责遍历查找发布的eventName 的方法
- remove 负责移除eventName 及事件
1 | class CreateEventHub{ |
手写Promise
核心
- new Promise(fn) fn只能为函数,且要立即执行
- Promise.then(res, fail) 接收的res和fail也是函数,且会在resole(reject)被调用时才会执行
1 | function MyPromise(fn) { |
以上。