【JavaScript】防抖、节流和函数柯理化 专栏:JavaScript
个人主页:繁星学编程
个人简介:一个不断提高自我的平凡人
分享方向:目前主攻前端,其他知识也会阶段性分享
格言:☀️没有走不通的路,只有不敢走的人!☀️
让我们一起进步,一起成为更好的自己!!!
作用:把一次传递两个参数,变成两次每次传递一个参数
目的:利用闭包,把第一次传递的参数保存下来(延长变量的生命周期)
function add(num1) {
return function (num2) {
return num1 + num2;
}
}
console.log(add(1));
/*
ƒ (num2) {
return num1 + num2;
}
*/
console.log(add(1)(2)); // 3
方式一:判断正则写在函数内部,需要判断的值在函数外部测试
function testpw(str) {
const reg = /^\w{6,12}$/;
return reg.test(str);
}
const res1 = testpw("12345jfiang");
const res2 = testpw("jfiang");
console.log(res1, res2); // true true
方式二:正则和测试的值都在函数外部同时传入
function testpw(reg, str) {
return reg.test(str);
}
const res1 = testpw(/^\w{6,12}$/, "1234");
const res2 = testpw(/^\w{6,12}$/, "1234fajin");
console.log(res1, res2); // false true
方式三:利用柯理化(闭包)封装
function testpw(reg) {
return function (str) {
return reg.test(str);
}
}
const test1 = testpw(/^\w{6,12}$/);
const res1 = test1("1223");
console.log(res1); // false
// 生成一个验证手机号的函数
const testPhone = testpw(/^1\d{10}$/);
// 校验手机号
const res2 = testPhone('2341200');
const res3 = testPhone('12312345678');
console.log(res2, res3); // false true
函数柯理化封装
是多个参数互相利用
需要两个功能
功能函数
收集参数
功能:实现拼接地址栏
http://localhost:8080/a/b
a : http
b : localhost
c : 8080
d : /a/b
功能函数 把 a b c d 拼接起来
// 并且要实现以下三种情况:
// 情况1
const res = curry(fn, 'http')
const res1 = res('localhost')
const res2 = res1('8080')
const res3 = res2('/a/b') // http://localhost:8080/a/b
console.log(res3);
// 情况2
// const res = curry(fn, 'http', 'localhost')
// const res1 = res('8080', '/a/b') // // http://localhost:8080/a/b
// 情况3
// const res = curry(fn, 'http', 'localhost', '8080', '/a/b')() // // http://localhost:8080/a/b
// console.log(res);
实现:
function fn(a, b, c, d) {
return a + '://' + b + ':' + c + d;
}
// 柯理化函数
function curry(fn, ...arg) {
/*
收集参数,判断参数的个数,够不够功能函数使用
如果够了:执行功能函数
如果不够:继续收集
*/
// 对外部收集的参数进行处理
let _arg = arg || []
// 需要用_arg的length和 功能函数的参数个数进行比对
// 获取函数形参的个数
let len = fn.length
return function (...arg) {
_arg = [..._arg, ...arg]
// 用处理好的参数进行数量判断
if (_arg.length === len) {
// 处理好的参数 ==== 功能函数参数相同
return fn(..._arg)
} else {
// 处理好的参数<功能函数参数
return curry(fn, ..._arg)
}
}
}
// const res = curry(fn)
通过setTimeout的方式,在一定的时间间隔内,将多次触发变成一次触发。(通俗的说是在最后一次点击间隔规定时间之后才能再次成功触发,否则触发不成功)
<input type="text" id="ipt">
<!-- 分割线 -->
ipt.oninput = function (e) {
console.log(e.target.value);
}
// 每键入一次就会将input框中的value值输出
防抖的实现思路:
递进优化实现步骤:
第一步:简单实现
let t = null;
ipt.oninput = function () {
clearInterval(t);
t = setTimeout(() => {
console.log(this.value);
}, 1500);
}
// 一直键入值等待1.5s后输出最终值
第二步:为了不污染全局,把变量放在函数里面
ipt.oninput = (function () {
let t = null;
return function () {
clearInterval(t);
t = setTimeout(() => {
console.log(this.value);
}, 1500);
}
})()
第三步:封装防抖函数
function prevent(cb) {
let t = null;
return function () {
clearInterval(t);
t = setTimeout(() => {
cb.call(this);
}, 1500);
}
}
ipt.oninput = prevent(function () {
console.log(this.value);
})
节流指的是减少一段时间内的触发频率。只有在上一次成功触发间隔规定时间之后,才能再次触发。
<input type="text" id="ipt">
<!-- 分割线 -->
ipt.oninput = function (e) {
console.log(e.target.value);
}
// 每键入一次就会将input框中的value值输出
节流的实现思路:
flag = false
;flag 是否=== true
来确定是否已经触发flag = false
执行代码,执行后将flag = true
递进优化实现步骤:
第一步:简单实现
let flag = false;
ipt.oninput = function () {
if (flag) return
flag = true;
setTimeout(() => {
console.log(this.value);
flag = false;
}, 2500);
}
第二步:使用闭包
ipt.oninput = (function () {
let flag = false;
return function () {
if (flag) return
flag = true;
setTimeout(() => {
console.log(this.value);
flag = false;
}, 2500)
}
})()
第三步:封装
function out(cb = () => { }) {
let flag = false;
return function () {
if (flag) return
flag = true;
setTimeout(() => {
cb.call(this);
flag = false;
}, 2500);
}
}
ipt.oninput = out(function () {
console.log(this.value);
})
结束语:
希望对您有一点点帮助,如有错误欢迎小伙伴指正。
点赞:您的赞赏是我前进的动力!
⭐收藏:您的支持我是创作的源泉!
✍评论:您的建议是我改进的良药!
一起加油!!!