跳到主要内容

Function

函数防抖

<input type="text" name="" value="">
<script type="text/javascript">
let el = document.querySelector('input')
el.addEventListener("input", debounce(A, 500))

function debounce(fn, delay) {
let timer = null
return function () {
timer && clearTimeout(timer)
timer = setTimeout(() => {
fn.call(this)
}, delay)
}
}

function A() {
console.log(this.value)
}
</script>

函数节流

function throttle (fn, time = 1000) {
let canRun = true;
return function () {
if (!canRun) return false;
canRun = false;
setTimeout(() => {
fn.call(this)
canRun = true
}, time)
}
}

setInterval(throttle(function() {
console.log("hello world")
}), 100)

实现bind函数

Function.prototype.bind = function (context, ...args) {
return (...newArgs) => {
return this.call(context, ...args, ...newArgs)
}
}

实现call/apply函数

Function.prototype.call = function (context, ...args) {
// context为null时,context设置为window
context = context || window
context.fn = this
let result = context.fn(...args)
delete context.fn
return result
}

// apply 只需要把参数修改即可
Function.prototype.apply = function (context, args) {
context = context || window
context.fn = this
let result = context.fn(...args)
delete context.fn
return result
}

递归

递归是很常见的,有的时候递归的写法会有微妙的差别。拿多维数组的扁平化举例。

// 外部函数获取内部函数的返回值
function flatter(arr) {
let newArr = []
arr.forEach(item => {
if (Array.isArray(item)) {
// newArr.push(...flatter(item))
newArr = newArr.concat(flatter(item))
}
else {
newArr.push(item)
}
})
return newArr
}

// 将值当作递归函数的参数
function flatter(arr, newArr = []) {
arr.forEach(item => {
if (Array.isArray(item)) {
flatter(item, newArr)
} else {
newArr.push(item)
}
})
return newArr
}