为什么限制设置超时,上下文和args为空?

时间:2014-04-22 06:12:17

标签: javascript underscore.js

所以我只是想在underscore.js中了解节流代码。

_.throttle = function(func, wait, options) {
    var context, args, result;
    var timeout = null;
    var previous = 0;
    options || (options = {});
    var later = function() {
        previous = options.leading === false ? 0 : _.now();
        timeout = null;
        result = func.apply(context, args);
        context = args = null;
    };
    return function() {
        var now = _.now();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0) {
            clearTimeout(timeout);
            timeout = null;
            previous = now;
            result = func.apply(context, args);
            context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
        return result;
    };
};

我想知道为什么context,args和timeout被设置为null。我原本以为他们是为了帮助垃圾收集而设置的。为了测试我创建了一个大字符串,将其传递给一个函数并限制该函数。我使用Chrome开发工具拍摄了两个快照 - 第一个使用将三个变量设置为null的行注释掉,另一个用未注释掉的行。

var dummyFunc1 = function(testStr) {
  console.log("HELLO");
};

var dummyFunc2 = function(testStr) {
  console.log("BOOM");
}

var dummyFunc3 = function(testStr) {
  console.log("STOOP");
}

var testStr = '';
for (var i = 0; i < 1000000; i++){
  testStr += i;
}

var largeThrottled1 = _.throttle(dummyFunc1, 1000);
var largeThrottled2 = _.throttle(dummyFunc2, 1000);
var largeThrottled3 = _.throttle(dummyFunc3,1000);

largeThrottled1(testStr);
largeThrottled1(testStr);

然而,似乎并没有太大区别。

enter image description here

那么为什么那些线呢?

1 个答案:

答案 0 :(得分:1)

我认为它与预防内存泄漏有关,正如您已经想到的那样 让我们假设您创建了大量的限制函数,用大量数据调用它们然后再也不调用它们。然后由_.throttle创建的函数仍将在闭包范围内保持对该数据的引用。它们在理论上仍然可以通过返回的函数到达,因此只要您不处理受限制的函数,GC就无法清理该数据。因此,将这些变量设置为null可确保不再使用任何不再使用的引用,从而防止内存泄漏。