寫這篇文章的目的是經(jīng)??吹介_發(fā)人員說:把字符串轉(zhuǎn)化為 JSON 對象,把 JSON 對象轉(zhuǎn)化成字符串等類似的話題,所以把之前收藏的一篇老外的文章整理翻譯了一下,供大家討論,如有錯誤,請大家指出,多謝。
本文的主題是基于 ECMAScript262-3 來寫的,2011 年的 262-5 新規(guī)范增加了 JSON 對象,和我們平時所說的 JSON 有關(guān)系,但是不是同一個東西,文章最后一節(jié)會講到新增加的 JSON 對象。
我想給大家澄清一下一個非常普遍的誤解,我認為很多 JavaScript 開發(fā)人員都錯誤地把 JavaScript 對象字面量
(Object Literals)稱為 JSON 對象
(JSON Objects),因為他的語法和JSON規(guī)范里描述的一樣,但是該規(guī)范里也明確地說了 JSON 只是一個數(shù)據(jù)交換語言
,只有我們將之用在 string 上下文的時候它才叫 JSON。
2 個程序(或服務(wù)器、語言等)需要交互通信的時候,他們傾向于使用 string 字符串因為 string 在很多語言里解析的方式都差不多。復(fù)雜的數(shù)據(jù)結(jié)構(gòu)經(jīng)常需要用到,并且通過各種各樣的中括號{},小括號(),叫括號<>
和空格來組成,這個字符串僅僅是按照要求規(guī)范好的字符。
為此,我們?yōu)榱嗣枋鲞@些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)作為一個 string 字符串,制定了標(biāo)準(zhǔn)的規(guī)則和語法。JSON 只是其中一種語法,它可以在 string 上下文里描述對象,數(shù)組,字符串,數(shù)字,布爾型和 null,然后通過程序間傳輸,并且反序列化成所需要的格式。YAML 和 XML(甚至 request params)也是流行的數(shù)據(jù)交換格式,但是,我們喜歡 JSON,誰叫我們是 JavaScript 開發(fā)人員呢!
引用 Mozilla Developer Center 里的幾句話,供大家參考:
JSON 是設(shè)計成描述數(shù)據(jù)交換格式的,他也有自己的語法,這個語法是 JavaScript 的一個子集。 { "prop": "val" } 這樣的聲明有可能是 JavaScript 對象字面量也有可能是 JSON 字符串,取決于什么上下文使用它,如果是用在 string 上下文(用單引號或雙引號引住,或者從 text 文件讀取)的話,那它就是 JSON 字符串,如果是用在對象字面量上下文中,那它就是對象字面量。
// 這是JSON字符串
var foo = '{ "prop": "val" }';
// 這是對象字面量
var bar = { "prop": "val" };
而且要注意,JSON 有非常嚴格的語法,在 string 上下文里{ "prop": "val" } 是個合法的 JSON,但{ prop: "val" }和{ 'prop': 'val' }卻是不合法的。所有屬性名稱和它的值都必須用雙引號引住,不能使用單引號。另外,即便你用了轉(zhuǎn)義以后的單引號也是不合法的,詳細的語法規(guī)則可以到這里查看。
大家伙可能嗤之以鼻:難道 JavaScript 代碼不是一個大的字符串?
當(dāng)然是,所有的 JavaScrip t代碼和 HTML(可能還有其他東西)都是字符串,直到瀏覽器對他們進行解析。這時候 .jf 文件或者 inline 的 JavaScript 代碼已經(jīng)不是字符串了,而是被當(dāng)成真正的 JavaScript 源代碼了,就像頁面里的 innterHTML 一樣,這時候也不是字符串了,而是被解析成 DOM 結(jié)構(gòu)了。
再次說一下,這取決于上下文,在 string 上下文里使用帶有大括號的 JavaScript 對象,那它就是 JSON 字符串,而如果在對象字面量上下文里使用的話,那它就是對象字面量。
開頭已經(jīng)提到,對象字面量不是 JSON 對象,但是有真正的 JSON 對象。但是兩者完全不一樣概念,在新版的瀏覽器里 JSON 對象已經(jīng)被原生的內(nèi)置對象了,目前有 2 個靜態(tài)方法:JSON.parse
用來將 JSON 字符串反序列化成對象,JSON.stringify
用來將對象序列化成 JSON 字符串。老版本的瀏覽器不支持這個對象,但你可以通過 json2.js 來實現(xiàn)同樣的功能。
如果還不理解,別擔(dān)心,參考一下的例子就知道了:
// 這是JSON字符串,比如從AJAX獲取字符串信息
var my_json_string = '{ "prop": "val" }';
// 將字符串反序列化成對象
var my_obj = JSON.parse( my_json_string );
alert( my_obj.prop == 'val' ); // 提示 true, 和想象的一樣!
// 將對象序列化成JSON字符串
var my_other_json_string = JSON.stringify( my_obj );
另外,Paul Irish提到 Douglas Crockford 在 JSON RFC 里用到了“JSON object”,但是在那個上下文里,他的意思是“對象描述成 JSON 字符串”不是“對象字面量”。
如果你想了解更多關(guān)于 JSON 的資料,下面的連接對你絕對有用: