2011-04-09 59 views
1

我需要通過JSON傳輸JavaScript對象並傳輸它的功能。我找到了一個獲取函數字符串並將其轉移的工作版本。然後我可以再次評估它們。在IE8中評估傳輸功能

//Create the function 
var myFunction = function(){alert('Hello, my Function!');} 
//get the functions String reprensentation 
var myFunctionTransferString = myFunction.toString(); 

//Now we transfered the object and want to have a function back 
var myTransferedFunction = eval('(' + myFunctionTransferString + ')'); 
//call the transfered function 
myTransferedFunction(); 

在這裏,我有這樣一個的jsfiddle:http://jsfiddle.net/bMjug/

這是在Firefox,Chrome和Safari的工作,因爲它應該(但你可以在微軟的軟件,極大pieace所謂的Internet Explorer無法猜測)。

在我想要評估函數的線上,我在IE8中收到消息fn is null or not an object

其實我找到了解決方案,但我真的不喜歡這個解決方案。如果我把變量聲明爲字符串我評價一個因爲我不期待的對象中刪除的括號了,會做什麼,我想:

eval('var myTransferedFunction = ' + myFunctionTransferString); 

,但我覺得這樣的黑客入侵,壞的解決方案。

有沒有人現在對這個問題更好?

在此先感謝

回答

3

對於它的價值,問題是由JScript中造成的錯誤解釋這一點:

(function x() {}) 

爲FunctionDeclaration而不是FunctionExpression,這樣做,而不是一個聲明-EVAL表達-EVAL。類似於{}沒有包裝托架的對象文字。你可以繞過它通過做一些更明確地將其推入解析表達式,如:

eval('['+myFunctionTransferString+'][0]'); 

嚴重不。永遠不要依賴函數的字符串表示,它不是標準化的,並且有many browser differences

即使函數分解是可靠的,也不能有用地保留一個函數,因爲函數比源文本表示要多得多。它包含的閉包不能被表示,而閉包在現實世界的JavaScript中更常見。

恐怕沒有廉價的方式來串行化/重新實例化JavaScript對象。 JSON子集是可靠的子集,其餘的你必須編寫自己的特定序列化格式。

+0

「的toString()」 我的函數對象上調用始終調用在ECMA腳本引擎在我的服務器上。所以我可以依靠字符串表示將永遠是它應該是。我只將它用於小型處理程序,因此在那裏不會有複雜的東西。你可能有一個鏈接來解釋FunctionDeclaration和FunctionExpression之間的區別嗎? – Chris 2011-04-09 16:54:19

+0

查看http://kangax.github.com/nfe/的介紹(儘管注意到「函數表達式:歸因於分組操作符」的例子正是你不會發生的事情,由於IE錯誤)。 – bobince 2011-04-09 22:22:35

+0

是的,這是一個很好的例子。但是這表明,一個函數表達式應該是一個函數表達式,它應該返回一個函數對象,我是對嗎? – Chris 2011-04-12 14:50:56

0

函數不是JSON規範的一部分。請記住,JSON規範是JavaScript語法的一個子集。

所以你的'黑客'解決方案實際上是更正確的解決方案。

+0

我知道。所以我得到的最好的方式是我在我的問題中描述的第一種方式。 ie8的「黑客」解決方案是我描述的第二個解決方案。實際上,我只希望第一個人也能夠工作: - / – Chris 2011-04-09 16:55:53

0

下面有一些砍死解決方案:

var fn = function() { alert("some text"); } 

var fnFromString = new Function("return " + fn.toString()); // function anonymous() { return function() { ... } } 
fnFromString = fnFromString(); // function() { alert("some text"); } 

,如果你立即執行腳本:

eval("(" + fn.toString() + ")()"); // fn executed.