JSON.parse與eval的區別
JSON.parse與eval和能將一個字符串解析成一個JSON對象,但還是有挺大區別。
測試代碼
var A = "{ a: 1 , b : ‘hello‘ }"; var B = "{ ‘a‘: 1 , ‘b‘ : ‘hello‘ }"; var C = "{‘a‘:1,‘b‘:‘hello‘}"; var D = ‘{"a":1,"b":"hello"}‘; var E = ‘{ "a" : 1 , "b" : "hello" }‘; var F = ‘{ "a" : 1 ,\n "b" : "hello" }‘; var G = ‘{ "a" : 1 , "b" : window.location.href="https://www.baidu.com" }‘;
JSON.parse執行:
例:JSON.parse(A);
A、B、C、G都不可轉,D、E、F都可以。
eval執行:
例:eval("("+A+")");
A到G都可以轉,特別到G時,頁面還跳轉到百度了。
JSON.parse
上面的演示例子可以看出,這方法只能解析屬性名是雙引號包裹的字符串對象,並會忽略換行和空格(值外面)。
但是,從MDN對JSON的描述,能解析的JSON字符串的條件完整如下:
JavaScript類型 | JSON與之區別 |
對象和數組 | 屬性名稱必須用雙引號包裹; 最後一個屬性後面不能有逗號。 |
數值 | 前導0不能使用(在 JSON.stringify 中將會被忽略,在 JSON.parse 會拋出錯誤); 小數點後面至少有一個數字。 |
字符串 | 只有有限的字符能夠被轉義; 不允許某些控制字符;但允許使用Unicode 行分隔符 (U+2028) 和段落分隔符 (U+2029) ; 字符串必須用雙引號括起來。 |
這方法還可以捕捉JSON中的語法錯誤,並允許你傳入一個函數,用來過濾或轉換解析結果。
瀏覽器兼容:IE8+
eval
eval函數可將一個JavaScript代碼字符串求值成特定的對象,所以解析成JSON對象只不過是作用之一。
為什麽eval()解析JSON字符串要加上括號?
原因是兩點:
1. json對象是以”{}”的方式來開始以及結束的,在JS中,它會被當成一個語句塊來處理。
2. 加上圓括號為了處理字符串為表達式,而不是語句(statement)來執行。
例子:
對象字面量 {},不加外層的括號,那麽eval會識別為JS代碼塊的開始和結束標記,那麽 {} 將會被認為是執行了一句空語句。
alert(eval("{}")); // return undefined alert(eval("({})"));// return object[Object]
不建議使用
雖然從演示例子看,eval的能力是強過於JSON.parse的,它可解析不規範的JSON字符串,但是G的例子也可以看出,eval是不安全的,特別是數據是第三方給予時候,你根本不知道eval之後它會幹什麽。
所以結論就是,乖乖用JSON.parse解析JSON對象。
$.parseJSON
jQuery也有提供解析JSON字符串的方法,$.parseJSON ,就目前jQuery版本來講,分為兩類。
2.x和3.x版本: $.parseJSON 都是直接使用 JSON.parse 的。
1.x版本:瀏覽器支持 JSON.parse 就用這個,不支持就進行校驗,確認是JSON字符串,則用
( Function( "return " + str ) )()
返回對象,否則返回無效JSON對象error。
PS:之所以能用Function處理,前提是校驗確認為JSON字符串,不然還是不安全的轉換方法。
總結
eval是強烈不建議用來解析JSON字符串,但是凡事無絕對,如果數據來源於你信任的並且格式也不大規範,那用它也不是不可以。
參考文獻
1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON
2. https://code.jquery.com/jquery-1.12.4.js
本文為轉載文章,轉自地址 :http://www.cnblogs.com/lovesong/p/6036650.html
JSON.parse與eval的區別