JSON的語法可以表示以下三種型別的值。
簡單值:使用與JavaScript相同的語法,可以在JSON中表示字串、數值、布林值和 null 。但JSON不支援JavaScript中的特殊值 undefined 。
物件:物件作為一種複雜資料型別,表示的是一組有序的鍵值對兒。而每個鍵值對兒中的值可以是簡單值,也可以是複雜資料型別的值。
陣列:陣列也是一種複雜資料型別,表示一組有序的值的列表,可以通過數值索引來訪問其中的值。陣列的值也可以是任意型別——簡單值、物件或陣列。
JSON不支援變數、函式或物件例項,它就是一種表示結構化資料的格式,雖然與JavaScript中表示資料的某些語法相同,但它並不侷限於JavaScript的範疇。
早期的JSON解析器基本上就是使用JavaScript的 eval()
函式。由於JSON是JavaScript語法的子集,因此 eval()
函式可以解析、解釋並返回JavaScript物件和陣列。ECMAScript 5對解析JSON的行為進行規範,定義了全域性物件 JSON 。JSON物件有兩個方法: stringify()
和 parse()
。在最簡單的情況下,這兩個方法分別用於把JavaScript物件序列化為JSON字串和把JSON字串解析為原生JavaScript值。
在序列化JavaScript物件時,所有函式及原型成員都會被有意忽略,不體現在結果中。此外,值為 undefined
的任何屬性也都會被跳過。結果中最終都是值為有效JSON資料型別的例項屬性。將JSON字串直接傳遞給 JSON.parse()
就可以得到相應的JavaScript值。
常常會用 JSON.parse
和 JSON.stringify
來深拷貝,如下面這樣。
let obb = {
a: 1,
b: function () {
console.log('b')
},
c: /\d+/
}
JSON.parse(JSON.stringify(obb)) // {a: 1, c: {}}
複製程式碼
因為JSON對有些資料不支援,所以無法完全拷貝各種資料型別的值。如果想完全拷貝,可以這樣。
function deepClone (obj) {
if (obj === null) return null
if (typeof obj !== 'object') return obj
if (obj instanceof RegExp) return new RegExp(obj)
if (obj instanceof Date) return new Date(obj)
let newObj = new obj.constructor
for (let key in obj) {
newObj[key] = deepClone(obj[key])
}
return newObj
}
複製程式碼