我们经常发现去抖实现与
func.apply(this, args)
我想这只是为了确保“this”指向返回的内部函数的上下文。
const debounce = function (func, wait = 1000) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args)
}, wait);
};
};
const handleSearch = function(param1, param2){
console.log(param1 + param2);
}
let debouncedFunc = debounce(handleSearch, 1000);
debouncedFunc("hello ", "world");
但是,如果我们简单地使用
args
调用该函数,而不用担心 apply
或 this
,我会得到相同的结果。那么这种方法是否存在任何潜在的陷阱,因为我们通常像前者一样实施?
const debounce = function (func, wait = 1000) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func(...args)
}, wait);
};
};
const handleSearch = function(param1, param2){
console.log(param1 + param2);
}
let res = debounce(handleSearch, 1000);
res("hello ", "world");
您将失去对
this
的访问权限。当您想要对尝试从对象访问数据的对象中的方法进行反跳时,这可能至关重要。考虑一个简单的例子,以下可能是您想要做的真正的计数器,并确保双击之类的事情不会重新触发它:
const myObj = {
data: 41,
increment: debounce(function() {
this.data++;
}, 100)
}
使用
.apply(this, args)
1 时,效果完全符合预期:
const debounce = function (func, wait = 1000) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args)
}, wait);
};
};
const myObj = {
data: 41,
increment: debounce(function() {
this.data++;
}, 100)
}
myObj.increment(); //increment call is debounced and will apply in 100ms
myObj.increment(); //second call is within the debounce period, thus ignored
setTimeout(
//the number printed is 42
() => console.log(`after debounce period: ${myObj.data}`),
150
);
当不向去抖动函数提供
this
的值时,结果为关闭:
const debounce = function (func, wait = 1000) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func(...args)
}, wait);
};
};
const myObj = {
data: 41,
increment: debounce(function() {
this.data++;
}, 100)
}
myObj.increment(); //increment call is debounced and will apply in 100ms
myObj.increment(); //second call is within the debounce period, thus ignored
setTimeout(
//the number printed is 41
() => console.log(`after debounce period: ${myObj.data}`),
150
);
在严格模式中,相同的代码甚至会抛出错误,因为
this
将是undefined
:
"use strict";
const debounce = function (func, wait = 1000) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func(...args)
}, wait);
};
};
const myObj = {
data: 41,
increment: debounce(function() {
this.data++;
}, 100)
}
myObj.increment(); //increment call is debounced and will apply in 100ms
myObj.increment(); //second call is within the debounce period, thus ignored
setTimeout(
//the number printed is 41
() => console.log(`after debounce period: ${myObj.data}`),
150
);
1 作为旁注,使用
.apply(this, arguments)
可能更容易 - 不需要可变参数,因为 arguments
对象 已经提供了它们。但总体来说影响不大。