鍍金池/ 教程/ HTML/ 根本沒有“JSON 對象”這回事!
代碼復(fù)用模式(避免篇)
S.O.L.I.D 五大原則之接口隔離原則 ISP
設(shè)計模式之狀態(tài)模式
JavaScript 核心(晉級高手必讀篇)
設(shè)計模式之建造者模式
JavaScript 與 DOM(上)——也適用于新手
設(shè)計模式之中介者模式
設(shè)計模式之裝飾者模式
設(shè)計模式之模板方法
設(shè)計模式之外觀模式
強大的原型和原型鏈
設(shè)計模式之構(gòu)造函數(shù)模式
揭秘命名函數(shù)表達式
深入理解J avaScript 系列(結(jié)局篇)
執(zhí)行上下文(Execution Contexts)
函數(shù)(Functions)
《你真懂 JavaScript 嗎?》答案詳解
設(shè)計模式之適配器模式
設(shè)計模式之組合模式
設(shè)計模式之命令模式
S.O.L.I.D 五大原則之單一職責(zé) SRP
編寫高質(zhì)量 JavaScript 代碼的基本要點
求值策略
閉包(Closures)
對象創(chuàng)建模式(上篇)
This? Yes,this!
設(shè)計模式之代理模式
變量對象(Variable Object)
S.O.L.I.D 五大原則之里氏替換原則 LSP
面向?qū)ο缶幊讨话憷碚?/span>
設(shè)計模式之單例模式
Function 模式(上篇)
S.O.L.I.D 五大原則之依賴倒置原則 DIP
設(shè)計模式之迭代器模式
立即調(diào)用的函數(shù)表達式
設(shè)計模式之享元模式
設(shè)計模式之原型模式
根本沒有“JSON 對象”這回事!
JavaScript 與 DOM(下)
面向?qū)ο缶幊讨?ECMAScript 實現(xiàn)
全面解析 Module 模式
對象創(chuàng)建模式(下篇)
設(shè)計模式之職責(zé)鏈模式
S.O.L.I.D 五大原則之開閉原則 OCP
設(shè)計模式之橋接模式
設(shè)計模式之策略模式
設(shè)計模式之觀察者模式
代碼復(fù)用模式(推薦篇)
作用域鏈(Scope Chain)
Function 模式(下篇)
設(shè)計模式之工廠模式

根本沒有“JSON 對象”這回事!

前言

寫這篇文章的目的是經(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 里的幾句話,供大家參考:

  1. 他們是固定的值,不是變量,讓你從“字面上”理解腳本。 (Literals)
  2. 字符串字面量是由雙引號(")或單引號(')包圍起來的零個或多個字符組成的。(Strings Literals)
  3. 對象字面量是由大括號({})括起來的零個或多個對象的屬性名-值對。(Object Literals)

何時是 JSON,何時不是 JSON?

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 字符串,而如果在對象字面量上下文里使用的話,那它就是對象字面量。

真正的 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 的資料,下面的連接對你絕對有用: