[英]Inner function context in underscore.js debounce function
我正在嘗試了解 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/
那么,這里需要上下文嗎? 需要應用什么上下文?
上下文是調用函數的去抖動版本的this
。 如果我們的對象上消除抖動的方法,那么我們將稱之為object.debounced_function
,但我們希望原有的功能與同一對象調用this
。
如果去抖動的函數不是對象方法,或者沒有this
被調用,那么 context 將為 null 或window
或其他東西,原始函數將作為this
被調用,但沒有人會在意。
我假設您了解Function#apply
方法,該方法調用具有特定上下文 ( this
) 和參數集的函數。
你能舉出具體的例子嗎? 這是我的代碼,但 1. apply(context, args); 2.函數(); 他們安慰同樣但他們不應該?
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)();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.