1.手写call,apply,bind
call() 方法
使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数
语法:function.call(thisArg, arg1, arg2, ...)
测试代码段
function foo(){
console.log(this.name)
console.log(arguments)
}
const obj={
name:'菜菜'
}
Function.prototype.mycall = function(thisArg,...args){
const fn = Symbol('fn')
thisArg = thisArg || window
thisArg[fn] = this
const result = thisArg[fn](...args)
delete thisArg[fn]
return result
}
测试结果
foo.myCall(obj)
2.防抖节流
防抖,即
短时间内大量触发同一事件,只会执行一次函数
,实现原理为设置一个定时器,约定在xx毫秒后再触发事件处理,每次触发事件都会重新设置计时器,直到xx毫秒内无第二次操作
,防抖常用于搜索框/滚动条的监听事件处理,如果不做防抖,每输入一个字/滚动屏幕,都会触发事件处理,造成性能浪费。
let el = document.querySelector('input')
el.addEventListener("input",debounce(A,500))
function debounce(fn,delay){
let timer = null
return function(){
if(timer)
clearTimeout
timer = setTimeout(() => {
fn.call(this)
}, delay);
}
}
function A(){
console.log(this.value)
}
防抖是
延迟执行
,而节流是间隔执行
,函数节流即每隔一段时间就执行一次
,实现原理为设置一个定时器,约定xx毫秒后执行事件,如果时间到了,那么执行函数并重置定时器
,和防抖的区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器
//定时器
function throttle(fn,wait){
let timer = null
return function(){
let args = arguments
let context = this
if(!timer){
setTimeout(() => {
timer = null
fn.apply(context,args)
}, wait);
}
}
}
//时间戳
function throttle(fn,wait){
let prev = 0
return function(){
let now = Date.now()
let context = this
let args = arguments
if(now-prev>wait){
fn.apply(context,args)
prev = now
}
}
}
3.数组扁平化
对于
[1, [1,2], [1,2,3]]
这样多层嵌套的数组,我们如何将其扁平化为[1, 1, 2, 1, 2, 3]
这样的一维数组呢:
1.使用ES6flat(infinity)
let arr = [1,2,[3,4,[5,[6]]]]
arr.falt(infinity)
2.序列化后正则
const arr = [1, [1,2], [1,2,3]]
const str = `[${JSON.stringify(arr).replace(/(\[|\])/g,'')}]`
JSON.parse(str)
3.递归
function flat(arr){
let newArr = []
arr.forEach(item=>{
if(Array.isArray(item))
//newArr.push(...flat(item))
newArr = newArr.concat(flat(item))
else{
newArr.push(item)
}
}
)
return newArr
}
4.reduce()递归
function flat(arr){
return arr.reduce((pre,cur)=>{
return pre.concat(cur instanceof Array ? flat(cur):cur)
},[])
}
flat(arr)
5.迭代+展开运算符
//每次while都会合并一层数组
while(arr.some(Array.isarray)){
arr = [].concat(...arr)
}