前些日子用到了eval()處理json數據,習慣於每次添加'('+json+')'處理數據,也沒去深究爲何這麼作,恰好同事問我這個問題,瞬間啞口無言,只會如何操做,卻講不出緣由,這不符合咱程序員嚴謹的工做態度,仔細思考了一會,簡略的談談吧。jquery
可能會隨時腦洞,望各位見諒。程序員
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,是一種取代XML的數據結構,和xml相比,它更小巧但描述能力卻不差,因爲它的小巧因此網絡傳輸數據將減小更多流量從而加快速度。json
{"name":"json"}
如今還有不少人存在一些誤區,爲何{name:'json'}在檢驗時經過不了,數組
那是由於JSON官網最新規範規定瀏覽器
若是是字符串,那無論是鍵或值最好都用雙引號引發來,因此上面的代碼就是 {"name":"json"}網絡
不要反駁,官網就是這麼定義的。數據結構
若是從後臺接收json數據時,jquery將type設爲'json',或者利用$.getJSON()獲取,此時接收到的json是對象格式,不須要特殊處理,可直接使用;函數
可是若是接收的json格式是字符串類型,這時就須要將其轉換成對象格式了,兩種方法:eval() 和 new Function();url
var json='{"name":"lee","age":"15"}' str=window.eval('('+ json+')');
結果如圖:spa
咱們能夠看出解析後的json數據格式爲對象,方便咱們的後續操做處理,可是,咱們爲何要用'('+json+')'這樣的處理呢?
我的拙見以下:首先eval 可將字符串解析爲
還記得json的格式嗎?以"{"開頭對吧,在此那麼你還記的語句塊的格式嗎?也是以"{"開頭是吧,那麼問題就來了,eval解析時會把咱們的json當成語句塊,並且這個所謂的語句塊裏還有":",那麼極有可能會報錯,如圖:
在此隨便扯一點別的知識點。。
表達式:表達式,是由數字、算符、數字分組符號(括號)、自由變量和約束變量等以能求得數值的有意義排列方法所得的組合。約束變量在表達式中已被指定數值,而自由變量則能夠在表達式以外另行指定數值。
語句:JavaScript 語句向瀏覽器發出的命令。語句的做用是告訴瀏覽器該作什麼。一般咱們在每條可執行的語句結尾添加分號以分隔 JavaScript 語句,多條語句構成語句塊。
有些時候,表達式和語句會看不出區別,但其做用作不一樣,即有一些表達式會出如今語句的上下文中,爲了解決歧義,JavaScript語法禁止表達式以大括號"{"或關鍵字"function"開頭,若是要以"{"開頭的表達式能被正確解析,須要把這個"{}"包裹的內容放在"()"中,確保表達式被解析在表達式上下文中,若是表達式被解析在表達式上下文中,此時json解析後會轉換成對象類型,這就是咱們想要的結果。
表達式與語句的交集:
好了,原理講解完成,那麼各位應該明白以'('+json+')'格式處理eval接收數據的原理了吧,若是實在不明白,那就偷個懶,每次都不加'('+json+')',報錯了再加上,時間長了也就能明白了(千萬別聽個人,我開玩笑的%>_<%)。
可是,but,各位有沒有聽過前輩們講過一段話:
對於eval,要理解它,遠離它。
爲何呢?
爲何執行會緩慢呢? 這就要引出另外一位主角了:new Function();
先扯些別的,定義函數有三種方式,分別爲
來看代碼:
//1.取最大值 var getMax=new Function('Math.max(arguments)'); var max=getMax(1,4,5);
//2.處理json數據 var json='{"name":"json","age":"18"}'; data=(new Function('','return'+json))(); console.log(data);
結果如圖:
咱們再來看看所謂的代碼執行緩慢的問題是什麼,直接上代碼解釋:
// 1.eval function evalFun (){ var start= (new Date).getTime(); var func=eval('(function(a,b,c,d,e,f,g){return a*b*c*d*e*f*g;})'); var result= func(4234,3424,4234,4324,423,34234,53453); console.log(result); var time= (new Date).getTime()-start; return time; } // 2.new Function function newFun (){ var start= (new Date).getTime(); var func=new Function(['a','b','c','d','e','f','g'],'return a*b*c*d*e*f*g;'); var result=func(4234,3424,4234,4324,423,34234,53453); console.log(result); var time= (new Date).getTime()-start; return time; } t1=evalFun();//輸出處理時間差,單位ms t2=newFun(); console.log('時間比(new Function/eval):'+ t2/t1); //二者時間對比
兩種方法所處理數據相同,結果相同,請看時間比:
結果清晰明瞭,差異很大是吧,各位看官,您看懂了吧。
最後:鄙人才疏學淺,在此獻醜了,望各位前輩批評指正,在此感謝!------(未完待續) 2016-04-05