簡體   English   中英

underscore.js 去抖動函數中的內部函數上下文

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM