2012-04-17 77 views
2

我写了下面的函数。将本地函数传递给setTimeout()

function obj() 
{ 
    this.a; 
} 
obj.prototype.catch = function() 
{ 
    alert('Catched') 
} 
obj.prototype.do = function() 
{ 
    alert('called'); 
} 

我需要的是,之后的obj ::做电OBJ ::赶上()()被调用,调用必须从OBJ :: DO(内部进行) 因此,如何通过本地obj的功能的setTimeout

我曾尝试

obj.prototype.do = function() 
{ 
    window.setTimeout('"'+this.catch+'()"',1000); 
    alert('called'); 
} 

它不工作 然后我试图

obj.prototype.do = function() 
{ 
    window.setTimeout('"'+this+'.catch()"',1000); 
    alert('called'); 
} 

这给了我下面的错误铬控制台

Uncaught SyntaxError: Unexpected token ILLEGAL 

,所以我尝试了以下方法脏(是不是真的脏吗?)

obj.prototype.do = function() 
{ 
    this.pid = randomVal(100); 
    window['temp'+this.pid] = this; 
    window.setTimeout("temp"+this.pid+".catch();",1000); 
    alert('called'); 
} 
function randomVal(bound)//returns a random number between 0 and <bound> 
{ 
     return (Math.floor(Math.random()*(bound))); 
} 

这工作。

那么为什么前两种方法不worked.Is有任何其他的方式做同样的事情,没有全局变量.. 第二种方法和最后一个方法几乎相同。但是为什么我在gettng第二种方法的错误。 。? 的工作代码可以在这里找到 http://jsfiddle.net/jXhAs/

回答

1

使用闭包

obj.prototype.do = function() 
{ 
    window.setTimeout((function(that){ 
     return function(){ 
      that.catch(); 
     }; 
    })(this),1000); 
    alert('called'); 
} 
+0

当我们可以在'do'函数中创建一个本地作用域变量时,不需要引入* another *匿名函数。 – Quentin 2012-04-17 14:58:34

+0

@Quentin:有趣的是,这正是Neals的例子(如果你想象他的代码中包含“obj.prototype.do = function(){}”),那么你会批评他。我想有人正在寻求接受这里;-) – micha 2012-04-18 15:24:47

4

你应该通过一个功能setTimeout(不是字符串):

例子:

var self = this; 
setTimeout(function(){ 
    self.catch(); 
},1000); 
+0

当你可以保留一个本地引用时,你真的不应该创建一个新的全局对象。 – Quentin 2012-04-17 14:55:17

+0

无论如何,这是行不通的。 'this'不是你想要的变量(因为范围已经改变)并且字符串没有'catch'方法。 – Quentin 2012-04-17 14:57:51

7

不要将字符串传递给setTimeout ......永远。

var self = this; // Because the scope will change 
setTimeout(function() { self.catch() },1000); 

或者,如果你正在使用JS 1.8.5:

setTimeout(this.catch.bind(this),1000); 

可以read more about bind

+0

为什么不传递字符串?是否有任何性能下降,为什么? – 2012-04-17 14:54:29

+0

我想你可能会用这个变量声明覆盖'window.self'。 – jbabey 2012-04-17 14:54:56

+0

@JinuJD - 它们很难调试,缓慢,打破范围,并且如果用户数据进入它们可能会导致安全问题。 – Quentin 2012-04-17 14:56:07

0

为什么经历这一切的努力,只是传递的功能。

function obj() { 
    this.a; 
} 
obj.prototype. 
catch = function() { 
    alert('Catched') 
} 
obj.prototype.do = function() { 
    setTimeout(this. 
    catch, 1000); 
} 

var test = new obj(); 
test.do();​ 
+0

这将通过'this'关键字打破对'catch'内可用对象的引用。示例代码不使用它,但它显然是一个非常简化的示例(因为该函数除了发出警报外没有任何作用),并且真正的代码可能取决于它。 – Quentin 2012-04-17 15:00:08