前言 javascript
想要比較清楚的研究一個東西,並非說背下它的定義和幾個公式就完事了.因此對於JSON的解釋我也沒有興趣再COPY一遍它的英文全稱和完整命名,你們都知道它是一種數據交換格式,平時也就是看成一種數據類型那麼用了,這一點問題都沒有,本文只是在瞭解它的基本概念和前提上稍微深刻一下. java
正文 web
1. JSON格式
跨域
2001年爲了取代繁瑣而笨重的XML格式,JSON做爲一種輕量級的數據交換格式被提出,做爲1999年ECMA-262的一個子集.一經提出JSON就迅速的在Web應用上普及開來,由於相比於XML,JSON書寫十分簡單方便閱讀,同時由於是Javascript的子集因此符合JS的原生語法,能夠被解釋引擎直接處理.
數組
數據格式存在的目的是以必定的形式存儲數據,簡單說,JSON格式就是一種表示一系列"值"的方法,這些"值"存在於數組或者對象當中.
服務器
JSON雖然能夠存儲值,可是也要遵照必定的規則,固然結構的核心就是"key/vlaue".
數據結構
Object - 對象是一個無序的"key/value"集合.
函數
Array - 數組是值的有序集合.
this
Value - 值能夠是雙引號括起來的string,number,true,false,null,object,array,這些結構還能夠嵌套使用.
spa
String - 被雙引號包圍的任意Unicode字符集合.
Number - 數值與C和Java的數值很類似.
看了上面的結構,下面列舉一些書寫正確和錯誤的JSON格式:
// 書寫正確 ["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } {"names": ["張三", "李四"] } [ { "name": "張三"}, {"name": "李四"} ]
// 書寫錯誤 { name: "張三", 'age': 32 } // 屬性名必須使用雙引號 [32, 64, 128, 0xFFF] // 不能使用十六進制值 { "name": "張三", age: undefined } // 不能使用undefined { "name": "張三", "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), "getName": function() { return this.name; } } // 不能使用函數和日期對象
注意空數組和空對象都是符合規範的JSON值,null自己也沒有問題.看到這裏應該對JSON的格式有所瞭解了,最起碼糾正你們一個誤區,JSON不必定非要是{}或者[],而是二者都可.
2. JSON對象
咱們以前提到了JSON誕生於2001年,是ECMA-262的一個子集,後來JSON由於其流行程度以及實用性被加入到ECMA標準中.在ECMA5新增了JSON對象專門用來處理JSON格式,而且附加了stringify()和parse()兩個方法.
平時開發中有時咱們將JSON理解爲一個經過大括號和中括號進行結構標記的很長的字符串,這麼理解我感受也沒錯.
JSON.stringify(o) - 用於將對象轉爲JSON字符串. JSON.parse(string) - 用於將JSON字符串轉爲對象.
(1) stringify()
JSON.stringify("abc"); // ""abc"" JSON.stringify({ name: "張三" }); // {"name":"張三"}
這裏轉爲的時候若是遇到一個值是undefined或者是函數,那麼該值會被省略,除非這個值是數組的成員,則返回null.
JSON.stringify({ f: function() { }, a: [ function() {}, undefined ] }); // "{"a":[null,null]}"
第一個參數是要轉換的對象,第二個參數能夠沒有,也能夠是數組參數表示要轉化的屬性,或者是一個函數用來更改默認的轉換.
JSON.stringify({ a:1, b:2 }, ['a']); // "{"a":1}" function f(key, value) { if (typeof value === "number") { value = 2 * value; } return value; } JSON.stringify({ a:1, b:2 }, f) // "{"a":2,"b":4}"
stringify()方法還能夠接受第三個參數用來加強返回字符串的可讀性,以及更復雜的使用.可是這裏不推薦你們這麼用,由於使用JSON的目的就是爲了簡潔明瞭,若是把數據格式弄得太複雜就失去了自己含義了,因此一般狀況下"對象數組"這種複雜度應該足夠了.
(2) parse()
想要將一個字符串轉換爲JSON對象,那麼傳入的字符串必定要是有效的格式,不然程序會出錯,爲了防止意外能夠將這個過程放到try/catch代碼塊中.
JSON.parse('{}'); // {} JSON.parse('true'); // true JSON.parse('"foo"'); // "foo" JSON.parse('[1, 5, "false"]'); // [1, 5, "false"] JSON.parse('null'); // null var o = JSON.parse('{"name":"張三"}'); o.name // 張三
它也能夠接受一個第二參數,經過一個函數改變默認轉換的行爲.
function f(key, value) { if ( key === ""){ return value; } if ( key === "a" ) { return value + 10; } } var o = JSON.parse('{"a":1,"b":2}', f); o.a // 11 o.b // undefined
3. 誤區
很是多的人在使用了好久的JSON後都沒有弄明白什麼是JSON,雖然上面未來字符串和JSON對象的轉換.可是我依然要糾正,javascript中沒有一種數據類型叫作"JSON對象".能夠說JSON對象是在一種特殊環境上下文中產生的叫法,JSON在平常的表現形式更多的是一個擁有複雜數據結構的字符串,只是能夠被轉換爲對象.
// 這是JSON字符串 var foo = '{ "prop": "val" }'; // 這是對象字面量 var bar = { "prop": "val" };
4. 一點點擴展 - JSONP
說到這裏JSON就沒什麼東西了,做爲一種數據格式在外面平常使用的範疇它的深度也差很少就是這些了.寫着JSON到最後想起來了JSONP,因此順帶着也把它帶出來.
看名字就會以爲JSON和JSONP有那麼點好基友的味道,根據百度百科對JSONP的解釋是:JSON with Padding的略稱,一個非官方協議,容許在服務器集成Script tags返回給客戶端,經過JS callback的形式實現跨域訪問.
說到跨域我象看過的人應該對JSONP有一點印象,比較經典的說跨域的文章幾乎都提到了一種解決方案就是JSONP.這裏我不想解釋跨域的相關問題,因此我就針對JSONP解讀一下:
Ajax在請求文件時只要是跨域請求一律不許,可是Web頁面上調用JS文件則不受跨域的限制,因而咱們就想出一種方案,把服務器上的數據設法裝進JS格式的文件裏,而後讓客戶端調用.這時咱們想到JSON被JS原生支持並且能夠存儲複雜數據,這下好了,web端經過與調用腳本同樣的方式,調用跨域服務器上動態生成的js格式文件,客戶端在對這種JSON文件調用成功後就能夠隨便使用了.爲了方便客戶端使用數據,逐漸造成一種非正式的傳輸協議,被稱爲JSONP,它規定容許用戶傳遞一個callback參數給服務端,而後服務器返回數據時會將這個callback參數做爲函數名來包裹JSON數據.
結尾
關於JSON和相關的東西就寫了這些,參考了網上一些資料和本身的使用心得,水平有限,有不足的地方還請諒解,歡迎留言給我.