2010-09-29 86 views
5

爲什麼下面的代碼需要爲eval添加()爲什麼我們需要添加括號來評估JSON?

var strJson = eval("(" + $("#status").val().replace(";","") + ")"); 

PS:$("#status").val()就像{"10000048":"1","25000175":"2","25000268":"3"};

+0

你爲什麼首先使用'eval'?只要堅持: 'var strJson = $(「#status」)。val()。replace(「;」,「」);' – 2010-09-29 10:01:45

回答

3

eval需要JavaScript語句或表達式,但{...}將作爲語句表達式有效,並且JavaScript的語法首選語句。

作爲一種表達:

{"10000048":"1","25000175":"2","25000268":"3"} 

是一些屬性(你想要的)一個對象。

作爲語句時,它是一個塊:

{      // begin Block 
    "10000048":   // LabelledStatement (but the quotes are invalid) 
     "1",   // Expression, calculate string "1" then discard it, then 
      "25000175": // you can't put a label inside an expression 

這給出了一個錯誤。

(JavaScript的標籤可以用來標記使用特定的語句break/continue。他們有點無意義的,幾乎從來沒有使用過。)

因此,通過添加括號您解決歧義。只有表達式可以從(開始,所以內容在表達式上下文中被解析,給出對象字面值,而不是語句上下文。

順便說一句,這不是相當足以正確解釋所有可能的JSON值。由於JSON設計中的疏忽,字符U + 2028和U + 2029(兩個難懂的Unicode行結束字符)可以在JSON字符串文本中進行非轉義,但不能在JavaScript字符串文本中進行轉義。如果你想要安全,你可以逃脫它們,例如:

function parseJSON(s) { 
    if ('JSON' in window) return JSON.parse(s); 
    return eval('('+s.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')+')'); 
} 
4

返回的東西這取決於什麼該元素的值是(未知),在()包裝是考慮到可能的沒有輸入的安全路線在那裏。

編輯:既然你已經清除了它的JSON,這是無效的:

eval('{"10000048":"1","25000175":"2","25000268":"3"}'); 

但是,這將導致一個有效的對象返回:

eval('({"10000048":"1","25000175":"2","25000268":"3"})'); 
//effectively: 
eval('return {"10000048":"1","25000175":"2","25000268":"3"};'); 

圖片中JavaScript文件:

<script type="text/javascript"> 
    {"10000048":"1","25000175":"2","25000268":"3"} 
</script> 

這會失敗,它只是一個對象聲明內聯但不正確的語法......同樣的理由服務器支持JSONP的工作。


有點切的問題,但因爲你是包括jQuery的,你還不如用$.parseJSON()(將使用本地JSON.parse()如果可用)這樣的:

var strJson = $.parseJSON($("#status").val().replace(";","")); 
+0

嗨返回的val()類似於{「10000048」:「1 」, 「25000175」: 「2」, 「25000268」: 「3」}; – Ricky 2010-09-29 10:01:54

+0

爲什麼第一條語句是無效的 – Ricky 2010-09-29 10:06:20

+0

@Ricky - 這只是無效的語法,因爲它不直接在腳本中,因爲解析器不是將它看作表達式,而是有效地添加'()'是返回語句(因爲它切換到一個表達式,識別'{'作爲對象的開始,獲取/返回你關心的對象)。 – 2010-09-29 10:08:08

相關問題