6

我目前想知道是否有比通过参数'e'将此范围传递给lambda函数然后使用call()方法将其传递给'funkyFunction'更好的解决方案

setInterval(function(e){e.funkyFunction.call(e)}, speed, this)

(除了小问题:我一直在阅读有关 javascript 中内存泄漏的内容。lambda 函数如何影响我的内存?先定义它var i = function(e)...然后将其作为参数传递给 setInterval 更好吗?)

4

6 回答 6

12

我的情况可能有点不同,但这是我所做的:

var self = this;
setInterval(function() { self.func() }, 50);

我的情况是我的代码在一个类方法中,我需要保持正确的范围,因为我不希望“this”绑定解析为当前窗口。

例如。我想使用 setInterval 从 MyClass.init 运行 MyClass.animate,所以我将这个范围保持代码放入 MyClass.init

于 2011-02-03T19:26:54.333 回答
9

您可以使用本机绑定功能。

function Loop() {
    this.name = 'some name for test';
    setInterval( (function(){//wrap the function as object
        //after bind, "this" is loop refference
        console.log(this);
    }).bind(this), 1000 );// bind the object to this (this is Loop refference)
}

var loop = new Loop();

将此示例粘贴到控制台中以查看结果

于 2014-01-06T09:03:46.557 回答
5

简单地依赖外部范围定义的变量有什么问题?

(function() { 

    var x = {};
    setInterval(function() {
       funkyFunction.call(x)
    }, speed);

})();
于 2010-08-15T18:15:18.333 回答
1

我有同样的问题,但似乎没有内置的解决方案,所以这里是我一起打孔的快速解决方法:

function setScopedInterval(func, millis, scope) {
    return setInterval(function () {
        func.apply(scope);
    }, millis);
}

用法:

function MyClass() {
    this.timer = null;
    this.myFunc = function() { console.log('do some stuff'); };
    this.run = function() {
        this.timer = setScopedInterval(function () { this.myFunc(); }, 1000, this);
    };
    this.stop = function() { clearInterval(this.timer); };
}
var instance = new MyClass();
instance.run(); // will log to console every second
// until this line is called
instance.stop();

这仅涵盖传递实际函数的用例,而不是要执行的代码字符串。

至于您在使用此功能时有关内存泄漏的问题:使用setInterval匿名函数本身并不是问题。如果您在 lambda 中使用对对象的引用,只要匿名函数存在,此引用就会将引用的对象保留在内存中。我认为该函数被调用破坏了clearInterval

我认为首先将函数分配给变量没有任何好处,相反,它会创建另一个包含引用的变量,只要存在 anon func 就不会被垃圾收集......

于 2013-08-12T08:09:04.507 回答
1

你也可以看看YUI Framework. 它非常适合构建应用程序并且易于学习。

YUI2: YAHOO.lang.later(when, scope, fn, args, periodic);

YUI3: Y.later(when, scope, fn, args, periodic);

以更新为例

使用 YUI 和 jQuery(不要忘记启用 $.noConflict())

var jQuerySelector = jQuery("div[class^='form-field-']");

jQuerySelector.hide();
jQuery(jQuerySelector[0]).show();


YAHOO.lang.later(5000, jQuery, function(jQuerySelector) {
    if((!(this.index)) || (this.index == (jQuerySelector.length))) {
        this.index = 0;
    }

    jQuerySelector.hide();

    this(jQuerySelector[this.index++]).show();
}, jQuerySelector, true);

简而言之

  • 1º参数:每5000 毫秒5000,3º参数(一个函数)将被执行
  • 2º 参数: 使用this引用的jQuery对象
  • 3º参数:将要执行的函数。它接收作为参数的数组或作为 4º 参数传递的对象
  • 5º 参数:如果为 ,则为真,以提供的间隔连续执行,直到取消

http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_later

更新 不需要 $.noConflict() 因为 YUI 不以任何方式使用 $。

于 2013-08-14T06:46:59.720 回答
0

有两个重要的区别。

1) 你想要一个对传递参数的引用,以便超时函数可以跟踪对其所做的更改,还是你想要一个传递参数的克隆?

2)您是否希望能够捕获对超时的引用以防万一您想取消它?(是的!)

// Normal setTimeout: retains a reference to `test` and returns the bad value
var test = 'test: good';
var timer = setTimeout(function() { console.log(test); }, 1000);
test = 'test: bad';

// Test2 receives a clone of `test2` and returns the good value, but does so right away, not on a timeout
var test2 = 'test2: good';
var timer2 = setTimeout((function() { console.log(test2); })(test2), 1000);
test2 = 'test2: bad';

// Test3 receives a clone of `test3` and returns the good value, but doesn't return a reference to the timeout, and can't be canceled
var test3 = 'test3: good';
var timer3 = function(test3) { setTimeout(function() { console.log(test3); }, 1000); }(test3);
test3 = 'test3: bad';

// Test4 receives a clone of `test4` and returns the good value, and correctly returns timeout reference
var test4 = 'test4: good';
var timer4 = function(test4) { return setTimeout(function() { console.log(test4); }, 1000); }(test4);
test4 = 'test4: bad';

// Test5 retains a reference to `test5` and returns the bad value
var test5 = 'test5: good';
var timer5 = setTimeout((function() { console.log(test5); }).bind(test5), 1000);
test5 = 'test5: bad';

// Did we capture references to the timeouts?
console.log(typeof timer);
console.log(typeof timer2);
console.log(typeof timer3);
console.log(typeof timer4);
console.log(typeof timer5);
于 2014-12-01T00:51:00.170 回答