实现防抖函数

防抖函数原理:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

适用场景

  • 按钮提交场景:防止多次提交按钮,只执行最后提交的一次
  • 服务端验证场景:表单验证需要服务端配合,只执行一段连续的输入事件的最后一次,还有搜索联想词功能类似

简单实现

1
2
3
4
5
6
7
8
9
10
11
const debounce = (fn, delay = 500) => {
let timer = null
const args = [].slice.call(arguments)

return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}

实现类的继承

类的继承在几年前是重点内容,有n种继承方式各有优劣,es6普及后越来越不重要,那么多种写法有点『回字有四样写法』的意思,如果还想深入理解的去看红宝书即可,我们目前只实现一种最理想的继承方式。

Read More

模拟JavaScript中的new

new 操作符做了那些事情

  • 创建一个全新的对象
  • 将对象的__proto__指向(链接)构造函数的prototype属性(原型对象)
  • 构造函数通过call或者apply执行,将创建的对象传入,使this指向创建的对象
  • 如果函数没有返回对象类型Object(Function、Array、Data、RegExg、Error),则返回创建的对象的引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function objectFactory () {
const obj = new Object()
// 获取第一个参数,即构造函数
const Constructor = [].shift.call(arguments)

// 更改obj的__proto__为构造函数的原型对象
obj.__proto__ = Constructor.prototype

// 执行构造函数,并改变this指向,为obj绑定属性
const ret = Constructor.apply(obj, arguments)

// 判断ret类型是否为对象类型,是则返回ret,否则返回obj的引用
return typeof ret === "object" ? ret : obj
}

function A (name) {
this.name = name
}

const a = objectFactory(A, '张三') // A { name: "test" }

实现节流函数

防抖函数原理:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

适用场景

  • 拖拽场景:固定时间内只执行一次,防止超高频次触发位置变动
  • 缩放场景:监控浏览器resize
  • 动画场景:避免短时间内多次触发动画引起性能问题

简单实现

1
2
3
4
5
6
7
8
9
10
11
12
const throttle = (fn, delay) => {
let flag = null

return (...args) => {
if (!flag) return
flag = false
setTimeout(() => {
fn.apply(this, args)
flag = true
}, delay)
}
}