js高级之手写代码总结
前言(吐槽)
相信在准备面试的朋友们, 除了苦逼的朗读并背诵八股文之外, 还要去力扣去刷各种算法题吧 谁让各个互联网大厂就爱这一套呢, 不过说实话, 鄙人也发自内心的认为数据结构与算法真滴非常之超级重要, 所以呢我就替大家总结一些js高级中我们常用到的一些方法和函数咯
防抖节流
相信大家对于这两个函数是非常熟悉的, 从我们开始学习js开始, 到我们学了几百年js后, 在面试中出现的概率也非常之高, 接下来我就从最简单的实现然后一步步完善这两个函数吧!
防抖
-
- 基本实现
// fn: 目标函数, delay: 限制时间
function(fn, delay){
// 1.用于记录上一次事件触发的timer
let timer = null
// 2.触发事件时执行的函数
const _debounce = () => {
// 2.1.如果有再次触发(更多次触发)事件, 那么取消上一次的事件
if (timer) clearTimeout(timer)
// 2.2.延迟去执行对应的fn函数(传入的回调函数)
timer = setTimeout(() => {
fn()
timer = null // 执行过函数之后, 将timer重新置null
}, delay);
}
// 返回一个新的函数
return _debounce
}
-
- this和参数的绑定
function hydebounce(fn, delay) {
// 1.用于记录上一次事件触发的timer
let timer = null
// 2.触发事件时执行的函数
const _debounce = function(...args) {
// 2.1.如果有再次触发(更多次触发)事件, 那么取消上一次的事件
if (timer) clearTimeout(timer)
// 2.2.延迟去执行对应的fn函数(传入的回调函数)
timer = setTimeout(() => {
fn.apply(this, args)
timer = null // 执行过函数之后, 将timer重新置null
}, delay);
}
// 返回一个新的函数
return _debounce
}
-
- 取消功能的实现
function hydebounce(fn, delay) {
// 1.用于记录上一次事件触发的timer
let timer = null
// 2.触发事件时执行的函数
const _debounce = function(...args) {
// 2.1.如果有再次触发(更多次触发)事件, 那么取消上一次的事件
if (timer) clearTimeout(timer)
// 2.2.延迟去执行对应的fn函数(传入的回调函数)
timer = setTimeout(() => {
fn.apply(this, args)
timer = null // 执行过函数之后, 将timer重新置null
}, delay);
}
// 3.给_debounce绑定一个取消的函数
_debounce.cancel = function() {
if (timer) clearTimeout(timer)
}
// 返回一个新的函数
return _debounce
}
-
- 立即执行功能增加
function hydebounce(fn, delay, immediate = false) {
// 1.用于记录上一次事件触发的timer
let timer = null
let isInvoke = false
// 2.触发事件时执行的函数
const _debounce = function(...args) {
// 2.1.如果有再次触发(更多次触发)事件, 那么取消上一次的事件
if (timer) clearTimeout(timer)
// 第一次操作是不需要延迟
if (immediate && !isInvoke) {
fn.apply(this, args)
isInvoke = true
return
}
// 2.2.延迟去执行对应的fn函数(传入的回调函数)
timer = setTimeout(() => {
fn.apply(this, args)
timer = null // 执行过函数之后, 将timer重新置null
isInvoke = false
}, delay);
}
// 3.给_debounce绑定一个取消的函数
_debounce.cancel = function() {
if (timer) clearTimeout(timer)
timer = null
isInvoke = false
}
// 返回一个新的函数
return _debounce
}
-
- 获取返回值(使用回调函数)
function hydebounce(fn, delay, immediate = false, resultCallback) {
// 1.用于记录上一次事件触发的timer
let timer = null
let isInvoke = false
// 2.触发事件时执行的函数
const _debounce = function(...args) {
return new Promise((resolve, reject) => {
try {
// 2.1.如果有再次触发(更多次触发)事件, 那么取消上一次的事件
if (timer) clearTimeout(timer)
// 第一次操作是不需要延迟
let res = undefined
if (immediate && !isInvoke) {
res = fn.apply(this, args)
if (resultCallback) resultCallback(res)
resolve(res)
isInvoke = true
return
}
// 2.2.延迟去执行对应的fn函数(传入的回调函数)
timer = setTimeout(() => {
res = fn.apply(this, args)
if (resultCallback) resultCallback(res)
resolve(res)
timer = null // 执行过函数之后, 将timer重新置null
isInvoke = false
}, delay);
} catch (error) {
reject(error)
}
})
}
// 3.给_debounce绑定一个取消的函数
_debounce.cancel = function() {
if (timer) clearTimeout(timer)
timer = null
isInvoke = false
}
// 返回一个新的函数
return _debounce
}
节流
-
- 基本实现
function hythrottle(fn, interval) {
let startTime = 0
const _throttle = function() {
const nowTime = new Date().getTime()
const waitTime = interval - (nowTime - startTime)
if (waitTime <= 0) {
fn()
startTime = nowTime
}
}
return _throttle
}
-
- this和参数的绑定
function hythrottle(fn, interval) {
let startTime = 0
const _throttle = function(...args) {
const nowTime = new Date().getTime()
const waitTime = interval - (nowTime - startTime)
if (waitTime <= 0) {
fn.apply(this, args)
startTime = nowTime
}
}
return _throttle
}
-
- 立即执行控制
function hythrottle(fn, interval, leading = true) {
let startTime = 0
const _throttle = function(...args) {
// 1.获取当前时间
const nowTime = new Date().getTime()
// 对立即执行进行控制
if (!leading && startTime === 0) {
startTime = nowTime
}
// 2.计算需要等待的时间执行函数
const waitTime = interval - (nowTime - startTime)
if (waitTime <= 0) {
fn.apply(this, args)
startTime = nowTime
}
}
return _throttle
}
-
- 尾部执行控制
function hythrottle(fn, interval, { leading = true, trailing = false } = {}) {
let startTime = 0
let timer = null
const _throttle = function(...args) {
// 1.获取当前时间
const nowTime = new Date().getTime()
// 对立即执行进行控制
if (!leading && startTime === 0) {
startTime = nowTime
}
// 2.计算需要等待的时间执行函数
const waitTime = interval - (nowTime - startTime)
if (waitTime <= 0) {
// console.log("执行操作fn")
if (timer) clearTimeout(timer)
fn.apply(this, args)
startTime = nowTime
timer = null
return
}
// 3.判断是否需要执行尾部
if (trailing && !timer) {
timer = setTimeout(() => {
// console.log("执行timer")
fn.apply(this, args)
startTime = new Date().getTime()
timer = null
}, waitTime);
}
}
return _throttle
}
-
- 取消功能实现
function hythrottle(fn, interval, { leading = true, trailing = false } = {}) {
let startTime = 0
let timer = null
const _throttle = function(...args) {
// 1.获取当前时间
const nowTime = new Date().getTime()
// 对立即执行进行控制
if (!leading && startTime === 0) {
startTime = nowTime
}
// 2.计算需要等待的时间执行函数
const waitTime = interval - (nowTime - startTime)
if (waitTime <= 0) {
// console.log("执行操作fn")
if (timer) clearTimeout(timer)
fn.apply(this, args)
startTime = nowTime
timer = null
return
}
// 3.判断是否需要执行尾部
if (trailing && !timer) {
timer = setTimeout(() => {
// console.log("执行timer")
fn.apply(this, args)
startTime = new Date().getTime()
timer = null
}, waitTime);
}
}
_throttle.cancel = function() {
if (timer) clearTimeout(timer)
startTime = 0
timer = null
}
return _throttle
}
-
- 获取返回值(回调函数)
function hythrottle(fn, interval, { leading = true, trailing = false } = {}) {
let startTime = 0
let timer = null
const _throttle = function(...args) {
return new Promise((resolve, reject) => {
try {
// 1.获取当前时间
const nowTime = new Date().getTime()
// 对立即执行进行控制
if (!leading && startTime === 0) {
startTime = nowTime
}
// 2.计算需要等待的时间执行函数
const waitTime = interval - (nowTime - startTime)
if (waitTime <= 0) {
// console.log("执行操作fn")
if (timer) clearTimeout(timer)
const res = fn.apply(this, args)
resolve(res)
startTime = nowTime
timer = null
return
}
// 3.判断是否需要执行尾部
if (trailing && !timer) {
timer = setTimeout(() => {
// console.log("执行timer")
const res = fn.apply(this, args)
resolve(res)
startTime = new Date().getTime()
timer = null
}, waitTime);
}
} catch (error) {
reject(error)
}
})
}
_throttle.cancel = function() {
if (timer) clearTimeout(timer)
startTime = 0
timer = null
}
return _throttle
}
以上的优化在面试中遇见的概率比较低, 但是基础版本我相信每个前端人都是必须要掌握的
暂时先更新到这哦