我目前想知道是否有更好的解决方案,而不是通过参数'e'将此范围传递给lambda函数,然后将其传递给'funkyFunction '使用call() - 方法
setInterval(function(e){e.funkyFunction.call(e)}, speed, this)
(除了小问题:我一直在阅读有关javascript中内存泄漏的内容.lambda函数如何影响我的内存?最好先定义它,如var i = function(e)...
,然后将其作为setInterval的参数?)
答案 0 :(得分:9)
我的情况可能有点不同,但这就是我所做的:
var self = this;
setInterval(function() { self.func() }, 50);
我的情况是我的代码在一个类方法中,我需要保持正确的范围,因为我不希望'this'绑定解析到当前窗口。
例如。我想使用setInterval从MyClass.init运行MyClass.animate,所以我将这个scope-keep代码放入MyClass.init
答案 1 :(得分:5)
您可以使用本机绑定功能。
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();
将此示例粘贴到控制台中以查看结果
答案 2 :(得分:4)
简单地依赖外部范围定义的变量有什么问题?
(function() {
var x = {};
setInterval(function() {
funkyFunction.call(x)
}, speed);
})();
答案 3 :(得分: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函数存在就不会被垃圾收集... < / p>
答案 4 :(得分: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);
简而言之
请参阅http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_later
<强>更新强> 不需要$ .noConflict()因为YUI不以任何方式使用$。
答案 5 :(得分: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);