柯里化 防抖 节流 基本都是用闭包的思想 一个函数接受一个函数作为参数这个函数就可以访问到外层函数的变量,外层函数相当于是一个容器,内部函数运行始终在这个容器中。
柯里化currying
https://www.lodashjs.com/docs/lodash.curry lodash 官网柯里化使用文档
核心
- 通过闭包容器累加参数
- 如果参数长度和执行函数的参数长度一样了则执行 ```javascript
/**
- args是每次传递进来的参数, 这里每次传递一个如,通过闭包容器作用累加到和函数参数相同的长度
- @param {*} fn 要执行的函数
- @param {…any} args 传递的参数
*/
function currying(fn, …args) {
// fn.length 传递进来的函数需要的参数,如果参数不如fn要接受的参数多,则继续递归,如果参数一样多就执行传递进来的fn
return args.length >= fn.length
}? fn(...args)
: (...args2) => {
return currying(fn, ...args, ...args2)
}
// 测试
function add(x, y, z) {
return x + y + z
}
const cur = currying(add)
console.log(cur(1)(2)(3), “~~”)
<a name="630fa48e"></a>
## 防抖debounce
**核心**
- 利用闭包原理,debonuce函数接收一个函数作为参数,返回一个函数,这个返回的函数可以访问到debonuce容器的timer参数
- 非立即执行核心
- 在settimeout完成后执行传入的函数
- 如果重复出发则cleartimeout清楚这个timer
- 立即执行版核心
- 在timer基础上添加一个flag,默认是true,如果是true则执行传递进来的函数,第一次默认执行完成;
- 第一次执行成功后设置flag为false
- 通过settimeout来控制这个flag为true,如果在一段时间内没有再触发函数则settimeout到时间
```javascript
/**
* 防抖函数
*
* - 立即执行
* - 非立即执行
* @param {*} fn
* @param {*} delay
* @param {*} isImmediate
*/
function debounce(fn, delay = 500, isImmediate = true) {
let timer = null;
let flag = true
if (isImmediate === true) {
// 立即执行
return function () {
if (timer) {
clearTimeout(timer);
timer = null
}
if (flag === true) {
fn.apply(this, arguments);
flag = false
}
timer = setTimeout(() => {
flag = true
timer = null
}, delay)
}
} else {
// 非立即执行
return function () {
if (timer) {
clearTimeout(timer);
timer = null
}
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = null;
}, delay)
}
}
}
// 测试
window.addEventListener("scroll", debounce(() => {
console.log('---')
}))
更详细的看我这篇防抖、节流
语雀内容
flatten 扁平化数组
核心
数组ans传递是传递的引用,不会随着递归进入新调用栈而重置内容,
- 递归如果是数组则继续向下找就好了~
- 递归的返回值除了最后一次中间的return ans没用到,
- 如果指定了层次则判断是否是数组如果是则深拷贝传入,防止数组变动引起不必要的麻烦。 ```javascript function isArrType(params) { const type = Object.prototype.toString.apply(params) === ‘[object Array]’ return type }
let ans = [] function flatten(arr, depth) { for (const iter of arr) { if (depth > 1) { if (isArrType(iter) === true) { flatten(iter, depth - 1) } else { ans.push(iter) } } else { if (isArrType(iter) === true) { ans.push(…iter) } else { ans.push(iter) } } } return ans }
// 测试 let arr = [1, [2, [3, [4]], 5]] const res = flatten(arr, 2) console.log(“res:”, res) ```
其他lodash常用方法
加减乘除(注意!没有浮点数运算优化的)
.add
.subtract
.multiply
.divide