防抖(debounce)
定义:设置单位时间内,触发高频事件后,函数只会执行一次。如果单位时间内事件再次触发事件,将其延迟,重新计算时间。
防抖:回城时,被打断,就要重新来。
1.简单实现防抖功能
function debounce(fn, wait) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(function () {
fn()
}, wait)
}
}
window.onresize = debounce(function () {
console.log('onresize')
}, 1000)
2.参数传递和this指向绑定
function debounce(fn, wait) {
let timer = null
return function (...args) {
clearTimeout(timer)
let context = this
timer = setTimeout(function () {
fn.apply(context, args)
}, wait)
}
}
window.onresize = debounce(function () {
console.log('onresize', this)
}, 1000)
防止抖动,单位时间内事件触发会被重置,避免事件被误伤触发多次。代码实现重在清零 clearTimeout,this 必须指向调用它的对象。防抖可以比作等电梯,只要有一个人进来,就需要再等一会儿。
应用场景:
-
登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖。
-
调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖。
-
input 框实时搜索,展示联想内容。
节流(throttle)
定义:节流函数用于限制函数的执行频率,在指定的时间间隔内,只允许函数执行一次。
节流:技能CD,技能CD未结束,无法使用技能。
1.使用时间戳
function throttle(fn, wait) {
let time = 0
return function (...args) {
let nowTime = Date.now()
let context = this
if (time - now > wait) {
fn.apply(context, args)
time = nowTime
}
}
}
window.onresize = throttle(function () {
console.log('onresize')
}, 300)
代码中的节流函数接受两个参数:fn和wait。fn是需要被节流的函数,wait是时间间隔的阈值。节流函数返回一个新的函数,在新函数中会对时间间隔进行判断。每当新函数被调用时,它会获取当前的时间戳(nowTime),并与上一次执行函数的时间戳(time)进行比较。如果两个时间戳的差值大于等于设定的时间间隔wait),则会执行传入的函数(fn)。更新时间戳为当前的时间(nowTime)在最后的代码中,将节流函数应用于window对象的onresize事件处理程序。每当浏览器窗口发生变化时,如果两次resize事件的时间间隔大于等于300毫秒,则会打印"onresize"。这样就能实现在指定的时间间隔内,限制onresize事件的触发频率,避免过多的执行。
通过 let context = this 将函数绑定的执行环境保存下来的。这是因为在返回的新函数中,由于闭包的特性,原始的函数,将不再拥有正确的执行上下文。为了保持始函数在正确的上下文中执行,我们将其保存到局部变量context中,并在调用fn时使用fn.apply(context, args)的方式来保证函数执行时的上下文正确。 这种保存和应用上下文的方式在 JavaScript 中经常用于确保函数在正确的对象上下文中运行,尤其在事件处理函数等回调函数中,以确保函数中的this关键字指向期望的对象。
应用场景:
scroll事件,每隔一秒计算一次位置信息等。- 浏览器播放事件,每个一秒计算一次进度信息等。
关于 JSON,以下代码输出什么
const obj = {
a: 1,
b: 2,
c: null,
d: undefined,
get e() {},
f: Symbol()
}
console.log(JSON.stringify(obj))
答案:
{"a":1,"b":2,"c":null}
使用JSON.stringify()方法,undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略。
什么是类数组?以及如何转化为数组?
在JavaScript中,类数组(array-like object)是指:具有长度(length)属性和按索引访问元素的对象,但没有数组原型上的方法(例如push和forEach)。
- 常见的类数组:
- arguments 对象
- DOM 元素集合对象
- 字符串
- 将类数组,转换为真正的数组。
-
Array.from()方法:const arrayLike = { 0: 'apple', 1: 'banana', 2: 'orange', length: 3 }; const array = Array.from(arrayLike); console.log(array); // ['apple', 'banana', 'orange'] -
Array.prototype.slice.call()方法:const arrayLike = { 0: 'apple', 1: 'banana', 2: 'orange', length: 3 }; const array = Array.prototype.slice.call(arrayLike); console.log(array); // ['apple', 'banana', 'orange']
Array(100).map(x => 1) 输出的结果是?
const array = Array(100).map(x => 1)
console.log(array)
答案:[empty × 100]
解析:Array(100) 的值为 [empty × 100] 的稀疏数组,map() 方法的callbackFn 仅在已分配值的数组索引处被调用,它不会在稀疏数组中的空槽处被调用。
那么如何让数组的每个元素都为1?
const arr = Array(100).fill(1)