## 前言
寫這篇文章的目的是經常看到開發人員說:把字符串轉化為JSON對象,把JSON對象轉化成字符串等類似的話題,所以把之前收藏的一篇老外的文章整理翻譯了一下,供大家討論,如有錯誤,請大家指出,多謝。
## 正文
本文的主題是基于ECMAScript262-3來寫的,2011年的262-5新規范增加了JSON對象,和我們平時所說的JSON有關系,但是不是同一個東西,文章最后一節會講到新增加的JSON對象。
英文原文:[http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/)
我想給大家澄清一下一個非常普遍的誤解,我認為很多JavaScript開發人員都錯誤地把JavaScript對象字面量(Object Literals)稱為JSON對象(JSON Objects),因為他的語法和[JSON規范](http://json.org/)里描述的一樣,但是該規范里也明確地說了JSON只是一個數據交換語言,只有我們將之用在string上下文的時候它才叫JSON。
## 序列化與反序列化
2個程序(或服務器、語言等)需要交互通信的時候,他們傾向于使用string字符串因為string在很多語言里解析的方式都差不多。復雜的數據結構經常需要用到,并且通過各種各樣的中括號{},小括號(),叫括號<>和空格來組成,這個字符串僅僅是按照要求規范好的字符。
為此,我們為了描述這些復雜的數據結構作為一個string字符串,制定了標準的規則和語法。JSON只是其中一種語法,它可以在string上下文里描述對象,數組,字符串,數字,布爾型和null,然后通過程序間傳輸,并且反序列化成所需要的格式。[YAML](http://en.wikipedia.org/wiki/YAML)和[XML](http://en.wikipedia.org/wiki/XML)(甚至[request params](http://benalman.com/news/2009/12/jquery-14-param-demystified/))也是流行的數據交換格式,但是,我們喜歡JSON,誰叫我們是JavaScript開發人員呢!
## 字面量
引用Mozilla Developer Center里的幾句話,供大家參考:
1. 他們是固定的值,不是變量,讓你從“字面上”理解腳本。 ([Literals](https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Literals))
2. 字符串字面量是由雙引號(")或單引號(')包圍起來的零個或多個字符組成的。([Strings Literals](https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#String_Literals))
3. 對象字面量是由大括號({})括起來的零個或多個對象的屬性名-值對。([Object Literals](https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Object_Literals))
## 何時是JSON,何時不是JSON?
JSON是設計成描述數據交換格式的,他也有自己的語法,這個語法是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' }確實不合法的。所有屬性名稱和它的值都必須用雙引號引住,不能使用單引號。另外,即便你用了轉義以后的單引號也是不合法的,詳細的語法規則可以到[這里查看](http://json.org/)。
## 放到上下文里來看
大家伙可能嗤之以鼻:難道JavaScript代碼不是一個大的字符串?
當然是,所有的JavaScript代碼和HTML(可能還有其他東西)都是字符串,直到瀏覽器對他們進行解析。這時候.jf文件或者inline的JavaScript代碼已經不是字符串了,而是被當成真正的JavaScript源代碼了,就像頁面里的innterHTML一樣,這時候也不是字符串了,而是被解析成DOM結構了。
再次說一下,這取決于上下文,在string上下文里使用帶有大括號的JavaScript對象,那它就是JSON字符串,而如果在對象字面量上下文里使用的話,那它就是對象字面量。
## 真正的JSON對象
開頭已經提到,對象字面量不是JSON對象,但是有[真正的JSON對象](https://developer.mozilla.org/en/Using_native_JSON)。但是兩者完全不一樣概念,在新版的瀏覽器里JSON對象已經被原生的內置對象了,目前有2個靜態方法:JSON.parse用來將JSON字符串反序列化成對象,JSON.stringify用來將對象序列化成JSON字符串。老版本的瀏覽器不支持這個對象,但你可以通過[json2.js](http://json.org/)來實現同樣的功能。
如果還不理解,別擔心,參考一下的例子就知道了:
~~~
// 這是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](http://paulirish.com/)提到Douglas Crockford在[JSON RFC](http://www.ietf.org/rfc/rfc4627.txt?number=4627)里用到了“JSON object”,但是在那個上下文里,他的意思是“對象描述成JSON字符串”不是“對象字面量”。
## 更多資料
如果你想了解更多關于JSON的資料,下面的連接對你絕對有用:
* [JSON specification](http://json.org/)
* [JSON RFC](http://www.ietf.org/rfc/rfc4627.txt?number=4627)
* [JSON on Wikipedia](http://en.wikipedia.org/wiki/JSON)
* [JSONLint - The JSON Validator](http://www.jsonlint.com/)
* [JSON is not the same as JSON](http://james.padolsey.com/javascript/json-is-not-the-same-as-json/)
- (1)編寫高質量JavaScript代碼的基本要點
- (2)揭秘命名函數表達式
- (3)全面解析Module模式
- (4)立即調用的函數表達式
- (5)強大的原型和原型鏈
- (6)S.O.L.I.D五大原則之單一職責SRP
- (7)S.O.L.I.D五大原則之開閉原則OCP
- (8)S.O.L.I.D五大原則之里氏替換原則LSP
- (9)根本沒有“JSON對象”這回事!
- (10)JavaScript核心(晉級高手必讀篇)
- (11)執行上下文(Execution Contexts)
- (12)變量對象(Variable Object)
- (13)This? Yes, this!
- (14)作用域鏈(Scope Chain)
- (15)函數(Functions)
- (16)閉包(Closures)
- (17)面向對象編程之一般理論
- (18)面向對象編程之ECMAScript實現
- (19)求值策略
- (20)《你真懂JavaScript嗎?》答案詳解
- (21)S.O.L.I.D五大原則之接口隔離原則ISP
- (22)S.O.L.I.D五大原則之依賴倒置原則DIP
- (23)JavaScript與DOM(上)——也適用于新手
- (24)JavaScript與DOM(下)
- (25)設計模式之單例模式
- (26)設計模式之構造函數模式
- (27)設計模式之建造者模式
- (28)設計模式之工廠模式
- (29)設計模式之裝飾者模式
- (30)設計模式之外觀模式
- (31)設計模式之代理模式
- (32)設計模式之觀察者模式
- (33)設計模式之策略模式
- (34)設計模式之命令模式
- (35)設計模式之迭代器模式
- (36)設計模式之中介者模式
- (37)設計模式之享元模式
- (38)設計模式之職責鏈模式
- (39)設計模式之適配器模式
- (40)設計模式之組合模式
- (41)設計模式之模板方法
- (42)設計模式之原型模式
- (43)設計模式之狀態模式
- (44)設計模式之橋接模式
- (45)代碼復用模式(避免篇)
- (46)代碼復用模式(推薦篇)
- (47)對象創建模式(上篇)
- (48)對象創建模式(下篇)
- (49)Function模式(上篇)
- (50)Function模式(下篇)
- (結局篇)