手写bind
- 第一个参数接收 this 对象
- 返回函数,根据使用方式
- 直接调用
- 构造函数
- 不改变 this 指向,忽略第一参数
- 拼接参数
- new 函数
Function.prototype.myBind = function(_this, ...args) {
const fn = this
return function F(...args2) {
return this instanceof F ? new fn(...args, ...args2)
: fn.apply(_this, args.concat(args2))
}
}
function Sum (a, b) {
this.v= (this.v || 0)+ a + b
returnthis
}
const NewSum = Sum.myBind({v: 1}, 2)
NewSum(3)
new NewSum(3)
手写call
- 第一参数接收 this 对象
- 改变 this 指向:将函数作为传入 this 对象的方法
- 展开语法,支持传入和调用参数列表
- 调用并删除方法,返回结果
Function.prototype.myCall = function(_this, ...args) {
if (!_this) _this = Object.create(null)
_this.fn = this
const res = _this.fn(...args)
delete _this.fn
return res
}
function sum (a, b) {
return this.v + a + b
}
sum.myCall({v: 1}, 2, 3)
手写apply
- 第一参数接收 this 对象
- 改变 this 指向:将函数作为传入 this 对象的方法
- 第二个参数默认数组
- 展开语法,支持调用参数列表
- 调用并删除方法,返回结果
Function.prototype.myApply = function(_this, args = []) {
if (!_this) _this = Object.create(null)
_this.fn =this
const res = _this.fn(...args)
delete _this.fn
return res
}
function sum (a, b) {
return this.v + a + b
}
sum.myApply({v: 1}, [2, 3])
手写new
- 第一参数作为构造函数,其余参数作为构造函数参数
- 继承构造函数原型创建新对象
- 执行构造函数
- 结果为对象,返回结果,反之,返回新对象
function myNew(...args) {
const Constructor = args[0]
const o = Object.create(Constructor.prototype)
const res = Constructor.apply(o, args.slice(1))
return res instanceof Object ? res : o
}
function P(v) {
this.v = v
}
const p = myNew(P, 1)
手写防抖
- 声明定时器
- 返回函数
- 一定时间间隔,执行回调函数
- 回调函数
function debounce(fn, delay) {
let timer = null
return function (...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
timer = null
fn.apply(this, args)
}, (delay + '') | 0 || 1000 / 60)
}
}
手写节流
- 声明定时器
- 返回函数
- 一定时间间隔,执行回调函数
- 回调函数
function throttle(fn, interval) {
let timer = null
return function (...args) {
if (timer) return
timer = setTimeout(() => {
timer = null
fn.apply(this, args)
}, (interval +'')| 0 || 1000 / 60)
}
}