2012-04-17 112 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