更多方法:https://juejin.im/post/6873513007037546510
1. 防抖
function debounce(func, ms = 1000) {
let timer;
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
func.apply(this, args)
}, ms)
}
}
// 测试
const task = () => { console.log('run task') }
const debounceTask = debounce(task, 1000)
window.addEventListener('scroll', debounceTask)
2. 节流
function throttle(func, ms = 1000) {
let canRun = true
return function (...args) {
if (!canRun) return
canRun = false
setTimeout(() => {
func.apply(this, args)
canRun = true
}, ms)
}
}
// 测试
const task = () => { console.log('run task') }
const throttleTask = throttle(task, 1000)
window.addEventListener('scroll', throttleTask)
3. new
function myNew(Func, ...args) {
const instance = {};
if (Func.prototype) {
Object.setPrototypeOf(instance, Func.prototype)
}
const res = Func.apply(instance, args)
if (typeof res === "function" || (typeof res === "object" && res !== null)) {
return res
}
return instance
}
// 测试
function Person(name) {
this.name = name
}
Person.prototype.sayName = function() {
console.log(`My name is ${this.name}`)
}
const me = myNew(Person, 'Jack')
me.sayName()
console.log(me)
4. bind
Function.prototype.myBind = function (context = globalThis) {
const fn = this
const args = Array.from(arguments).slice(1)
const newFunc = function () {
const newArgs = args.concat(...arguments)
if (this instanceof newFunc) {
// 通过 new 调用,绑定 this 为实例对象
fn.apply(this, newArgs)
} else {
// 通过普通函数形式调用,绑定 context
fn.apply(context, newArgs)
}
}
// 支持 new 调用方式
newFunc.prototype = Object.create(fn.prototype)
return newFunc
}
// 测试
const me = { name: 'Jack' }
const other = { name: 'Jackson' }
function say() {
console.log(`My name is ${this.name || 'default'}`);
}
const meSay = say.bind(me)
meSay()
const otherSay = say.bind(other)
otherSay()