2010-07-29 12 views
20

時,你可以告訴我這樣做的原因特定的語法結構爲什麼公開報價和支架的eval(「(」 + jsonString +「)」)解析JSON字符串

eval('(' + jsonString+ ')') 

當解析JSON文本。 Crockford說:「必須將文本包裝在parens中,以避免在JavaScript語法中模糊不清。」 here。那是什麼意思?

我們可以避免它嗎?

+4

如果你繼續閱讀你引用的那個句子後,從你鏈接到的頁面,你會看到爲什麼你不應該使用'eval'這個工作*在所有* – 2010-07-29 07:50:11

+3

這個理由避免eval是我知道的東西,無論如何感謝指出。 – nepsdotin 2010-07-29 08:12:07

回答

24

語法歧義到Crockford的指的是,如果一個開放的大括號上沒有表達上下文中找到,但將認識到像block,而不是像對象文本的開始。

例如:

{"foo": "bar"} // SyntaxError 

會給你一個語法錯誤,因爲它會被解釋爲一個塊,用於字符串「富」,和令牌:的意想不到的用途。

在另一方面,括號,正式名稱爲the grouping operator,只能計算表達式,所以我們不會有任何語法歧義,因爲塊只能在聲明背景下的預期。

({"foo": "bar"}) 

編輯:@el.pescado做一個有趣的問題:

你能解釋爲什麼的eval( '{}')是未定義的?

ECMAScript描述了一種內部類型來解釋語句的行爲,它被稱爲The Completion Specification Type。於完成型的

數值爲(type, value, target),形式,其中type可以normalbreakcontinuereturn,或者throw的三元組。

value可以是任何語言值或emptytarget任何標識符或empty

一個空塊(生產Block : {})明確地返回以下完成:

Return (normal, empty, empty). 

eval功能時,執行該代碼,和離開新創建執行上下文後,檢查所評估的代碼的結果完成,並在第7步,我們可以看到,undefined明確返回如果完成類型爲normal和完成值empty

...

7-如果result.type正常且其完成值爲空,則返回未定義的值。

...

+1

看到這個從未發佈的博客文章草稿,關於[完成類型](http://j.mp/gI9IRv) – CMS 2011-07-25 06:55:36

0

對象文本需要被包裹在括號正確在eval上下文和其他上下文進行評估:

eval('{}')未定義,例如。而eval('(' + '{}' + ')')評估爲對象。

如果你在控制檯嘗試了這個,例如:{"foo":"bar"}它會在你身上扔出一個無效標籤。用括號包裹它,它就成爲一個有效的表達式。

+0

downvoter可以解釋它嗎? – 2010-07-29 08:21:24

+1

你能解釋爲什麼'eval('{}')'是不確定的嗎? – 2010-07-29 08:58:49

+0

@ el.pescado:有趣的問題,檢查我[編輯答案](http://stackoverflow.com/questions/3360356/why-the-open-quote-and-bracket-for-eval-jsonstring-when-parsing- JSON/3360404#3360404)。 – CMS 2010-08-07 23:10:42

0

@ el.pescado,通過EVAL之後執行的字符串應該是JavaScript的理解。 即,如果您將以上字符串分配給變量如下

eval('var foo1 = {「foo」:「bar」}'); foo1.foo會回來吧

所以,我的假設是,因爲沒有像JavaScript中的「{」開頭,它是拋出錯誤。

+0

A [Block](http://ecma262-5.com/ELS5_HTML.htm#Section_12.1)被認爲是一個聲明,'eval('{}')'不會產生任何錯誤,它只是一個空的塊。 – CMS 2010-08-07 23:15:43

+0

'var'在你傳遞給'eval()'的字符串中似乎是非法的,你的代碼是否可以在一些舊的瀏覽器中工作(可能只有ES3支持)? – CoDEmanX 2015-03-16 18:34:47