我试图理解underscore.js去抖功能的机制: http://underscorejs.org/#debounce
以下是其原生代码:
_.debounce = function(func, wait, immediate) {
var timeout, args, context, timestamp, result;
var later = function() {
var last = _.now() - timestamp;
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function() {
context = this;
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
};
我遇到的问题是内部可退回函数中使用的上下文变量。我不明白为什么我们应该在这里使用它以及它包含什么上下文。 我尝试使用相同的函数与debounced函数的简单调用,而不应用任何上下文,它也运作良好。 这是我的小提琴这两个功能: http://jsfiddle.net/vlrt/fby9dhe0/11/
那么,这里的背景是必要的吗?需要应用哪些背景?
答案 0 :(得分:1)
上下文是this
,用于调用函数的去抖动版本。如果我们在对象上对方法进行去抖动,那么我们将使用object.debounced_function
来调用它,但是我们希望使用与this
相同的对象来调用原始函数。
如果debounced函数不是对象方法,或者调用没有this
,则上下文将为null或window
或其他内容,并且原始函数将被调用为{{{ 1}},但没人会关心。
我假设您理解this
方法,它调用具有特定上下文(Function#apply
)和参数集的函数。
答案 1 :(得分:0)
您能举一些具体的例子吗? 这是我的代码,但是 1.申请(context,args); 2. func(); 他们使用相同的控制台,但不应这样做吗?
function debounce(func, wait, immediate) {
// 'private' variable for instance
// The returned function will be able to reference this due to closure.
// Each call to the returned function will share this common timer.
var timeout;
this.a =222;
// Calling debounce returns a new anonymous function
return function() {
// reference the context and args for the setTimeout function
var context = this,
args = arguments;
// Should the function be called now? If immediate is true
// and not already in a timeout then the answer is: Yes
var callNow = immediate && !timeout;
// This is the basic debounce behaviour where you can call this
// function several times, but it will only execute once
// [before or after imposing a delay].
// Each time the returned function is called, the timer starts over.
clearTimeout(timeout);
// Set the new timeout
timeout = setTimeout(function() {
// Inside the timeout function, clear the timeout variable
// which will let the next execution run when in 'immediate' mode
timeout = null;
// Check if the function already ran with the immediate flag
if (!immediate) {
// Call the original function with apply
// apply lets you define the 'this' object as well as the arguments
// (both captured before setTimeout)
func.apply(context, args);
func();
}
}, wait);
// Immediate mode and no wait timer? Execute the function..
if (callNow) func.apply(context, args);
}
}
function test() {
this.a = 100;
this.b = 200;
}
test.prototype.m1 = function() {
console.log("m1", this.a);
}
var tt = new test();
debounce(tt.m1, 1000)();