JavaScript 内核精校教程
JavaScript 手写题:从原理到实现
用 call / apply / bind、防抖节流、深拷贝和事件总线检验语言机制是否真正掌握。
call、apply、bind实现
💡 提示
基本思路,使用隐式绑定,给传入的thisArg转换成一个对象,给新的对象添加一个属性fn,值为this,this即为调用者,也就是调用的函数,然后使用传入的thisArg去调用原来的函数
Function.prototype.myCall = function (thisArg, ...args) {
thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg)
Object.defineProperty(thisArg, 'fn', {
configurable: true,
enumerable: false,
value: this
})
//
thisArg.fn(...args)
delete thisArg.fn
}
手写防抖和节流
防抖
💡 提示
对于多次触发的事件,一定时间间隔内,只有最后一次事件会触发执行函数

function debounce(fn, delay, immediate = false) {
let timer = null
let isExc = false
function exec(...arg) {
// 立即执行一次
if (!isExc && immediate) {
fn.apply(this, arg)
isExc = true
return
}
// 清除定时器
timer && clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, arg)
clearTimeout(timer)
timer = null
}, delay)
}
// 可取消
exec.cancel = function () {
console.log('cancel');
timer && clearTimeout(timer)
}
return exec
}
节流
💡 提示
多次触发的事件按一定频率执行,减少执行次数

手写深拷贝
💡 提示
注意对不同类型的数据进行不同的操作,常见的对象、数组、函数,循环引用,set map,symbol等
循环引用可以使用weakmap来解决,symbol需要判断key和value