2011-10-22 115 views
0

我在使用setTimeout將對象傳遞給函數時遇到了麻煩;是否可以將對象傳遞給eval/setTimeout函數?

function alertObject(obj){ 
    alert(obj); //This is supposed to display "[object Object]" 
} 

function startCountdown(){ 
    var myObj = new myClass(); 
    setTimeout("alertObject("+ myObj +")",1000); 
} 

startCountdown(); 

當我運行這個,我得到一個錯誤,說「意外的標識符」。我知道我可以使用這樣的匿名函數;

setTimeout(function(){alertObject(myObj)},1000); 

而不是

setTimeout("alertObject("+ myObj +")",1000); 

但事實是我想知道爲什麼你不能使用eval()函數傳遞一個對象。它的工作原理與弦...

回答

2

你不能序列化的對象,同時保持該對象的身份。 (不限於JavaScript)。

'alertObject('+myObj+')'涉及將對象轉爲與toString()的字符串,從而產生alertObject([object Object]),這顯然是無效的JavaScript。

您可以提供toString()實現,它返回的東西是有效的JavaScript,並用它來創建一個新的對象,它是原來的對象:

function myClass(num) { 
    this.num= num; 
} 
myClass.prototype.toString= function() { 
    return 'new myClass('+this.num+')'; 
}; 

var a= new myClass(3); 
var b= eval(''+a);  // 'new myClass(3)' 
alert(a.num===b.num); // true 

,但它是不是同一個對象例如:

alert(a===b); // false 

,有沒有辦法讓實際的原始對象,短的,例如,保持對象的每個實例的查找,並通過一鍵即查找。

字符串中的隱藏代碼很糟糕。這是你不應該使用setTimeout和字符串參數的原因之一。與傳遞函數對象中去

0
setTimeout("alertObject("+ myObj +")",1000); 

相同

setTimeout("alertObject("+ ..object converted to string.. +")",1000); 

就是

setTimeout("alertObject([object Object])",1000); 

"alertObject([object Object])" 

不是有效的JavaScript,因此錯誤信息。

0

這是因爲對象只存在於函數內部。

setTimeout中的回調代碼將在全局範圍內調用(即window),而不是函數的作用域。由於myObj是函數內部的局部變量,因此它在全局範圍內不可用。

如果您在全局範圍內聲明變量,它將在您的函數結束時繼續存在,並且可以從回調代碼訪問該變量。

請注意,您應該在代碼中使用變量的名稱,而不是將變量的值連接到字符串中。如果你這樣做,你最終會得到類似"alertObject([Objecct object])"的東西,這當然不能運行。

var myObj; 
function startCountdown(){ 
    myObj = new myClass(); 
    setTimeout("alertObject(myObj)",1000); 
} 
0

你可以寫這樣的:

setTimeout(alertObject,1000,myObj); 

或像這樣:

setTimeout("alertObject(myObj)",1000); 

在您的例子MyObj中是序列化到"alertObject([Objecct object])"哪些不能跑。

0
setTimeout(function() { 
    alertObject(object); 
}, 1000); 

我認爲這是你需要的。

相關問題