1.防抖函数:
防抖函数就是在一定时间内没再触发事件时,执行程序;常用于搜索框搜索功能的优化;避免过于频繁的发送请求;
思路:
1.触发事件,清除延时函数,创建新的延时函数,并计时;
2.如果再次触发事件,执行函数,会clearTimeout移除延迟函数,创建新的延迟函数重新计时;
3.只有在一定时间间隔内没再触发事件,程序便执行;
function debounce(func, delay) {
var timer = null
return function() {
clearTimeout(timer)
timer = setTimeout(func, delay)
}
}
关于this和参数的问题:
this的问题比较容易总结,就是关于this隐式绑定丢失的问题,当实现隐式绑定的函数进行赋值操作时【参数传递属于一种隐式赋值】,就会发生this丢失,比较常见的就是延时函数中的this,它的this指向window;
解决问题的方法:
1.借助ES6的箭头函数,箭头函数会继承外层函数调用的this绑定;
2.使用 var self = this,保留this的绑定;
下面讨论参数的问题
ES5语法:
function foo(a, b) {
console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
setTimeout(function() {
console.log(arguments);//Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(event);//undefined
}, 500)
}
// foo(10, 29)
window.onload = function() {
foo(22, 33)
}
事件对象和arguments无法传递给延时函数
处理方法:
function foo(a, b) {
console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
var _arguments = arguments
console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
var _event = event
setTimeout(function() {
console.log(_arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(_event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
}, 500)
}
// foo(10, 29)
window.onload = function() {
foo(22, 33)
}
最终的基于ES5语法的防抖函数:
// 防抖函数
function debounce(func, delay) {
var timer = null
return function() {
clearTimeout(timer)
var _this = this
var _arguments = arguments
timer = setTimeout(function() {
func.apply(_this, _arguments)
}, delay)
}
}
ES6语法
function bar(c, d) {
console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
setTimeout(() => {
console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(event);//undefined
}, 500)
}
window.onload = function() {
bar(22, 33)
}
处理方法:
function bar(c, d) {
console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
var _event = event;
setTimeout(() => {
console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(_event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
}, 500)
}
window.onload = function() {
bar(22, 33)
}
最终的基于ES6语法的防抖函数【这里有疑问?????】:
function debounce(func, delay = 0) {
let timer = null;
return function (...arg) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arg)
}, delay)
}
}
2.节流函数
节流就是事件的触发必须在指定时间间隔之上生效,比如,间隔1s,触发后在1s内再次触发是无效的;
ES5实现:
function throttle(func, interval) {
var last = 0
return function() {
var _this = this;
var _arguments = arguments;
var now = new Date().getTime();
if(now - last > interval) {
func.apply(_this, _arguments)
last = now
}
}
}
ES6实现:
思路:
1.事件触发,执行函数,在间隔时间到之前,再次触发函数时,timer不为空,因此不会执行if后面的代码;
2.只有在间隔时间到了之后,在回调函数中将timer置空,从而可以实现节流的效果;
function throttle(func, interval) {
let timer = null;
return function(...args) {
if (!timer) {
timer = setTimeout(() => {
timer = null;
func.apply(this, args)
}, interval)
}
}
}