2013-05-08 92 views
5

我加載通過AJAX腳本文件,並運行它的內容我這樣做:使用`新Function`和性能問題

new Function('someargument',xhr.responseText)(somevalue); 

然而,根據MDN:

Function使用Function構造函數創建的對象在創建函數時被解析。這比聲明一個函數並在你的代碼中調用它的效率要低,因爲用函數聲明聲明的函數和其餘的代碼一起被解析。

我真的不太明白。如果聲明瞭一個函數,它仍然需要從文件的字符串格式中解析出來,那麼爲什麼要運行一個通過new Function加載的字符串會降低效率?

這對我來說真的是一件好奇的事情。我可以理解爲什麼它會在循環中變壞(不得不重新解析相同的字符串),但對於這樣的事情我不認爲有任何問題,是嗎?

+2

它的解析幾乎就像eval一樣,這已知很慢。我*假設*它應該快一點,因爲不需要連接範圍鏈。 – bfavaretto 2013-05-08 01:36:30

+0

不要通過AJAX發送函數,發送數據。在_.js_或'

6

我覺得他們說的是,如果你使用的功能構造函數在你的代碼是這樣的:

new Function('bar', 'console.log(bar);')); 

函數體被解析兩次:第一次作爲一個字符串被加載代碼的時候,第二次是在運行時構造函數。在你的情況下,你正在解析代碼後從ajax響應中創建函數,所以真的是一個完全不同的交易。

1

我不知道該MDN文章的作者意圖是什麼,但這裏有一個解釋。

許多現代JS解釋器使用優化編譯器來生成本機代碼。

例如,"JavaScriptCore, the WebKit JS implementation"說:三種形式之間

在這種情況下有分層編譯:初始解析和編譯產生的字節碼,可以與方法JIT進行優化,能夠由被優化DFG JIT。但實際上,在大多數平臺上不包括解釋器,所有代碼都通過JIT方法運行。

編譯器對編譯代碼的優化越完善,它可以執行的優化越多,因此函數的優化程度越高。例如,如果你知道每一個函數的引用都被用來立即用一個字符串作爲它的唯一參數來調用它,因爲它是在一個嚴格的函數體中定義的,那麼你可能可以避免爲它分配一個函數對象並在其主體中執行某些優化。

當您調用new Function時,優化編譯器不會獲取執行這些優化和其他優化所需的上下文。

+0

好吧,那麼這將如何適用於我的情況:使用'new Function'的代碼是預加載器,並且正在分析的代碼是我正在處理的遊戲的實際腳本。 – 2013-05-08 01:51:34

+1

@Kolink,它適用於您的情況嗎?你有沒有進行基準測試,看它是否有任何性能影響?當數據很容易收集時,不要在沒有數據的情況下做出性能決定。只要嘗試一下你所擁有的東西,以及使用'