伊莉討論區

標題: JavaScript 輕量資料格式 JSON [打印本頁]

作者: isve    時間: 2016-10-25 12:07 AM     標題: JavaScript 輕量資料格式 JSON

JSON 全名 JavaScript Object Notation,為 JavaScript 物件實字(Object literal)的子集,你可以在 Introducing JSON 找到詳細的 JSON 格式說明。大致而言,與物件實字格式類似,主要注意的是JSON:
•名稱為字串,必須用 "" 雙引號包括
•值可以是"雙引號包括的字串,或者是數字、true、false、null、物件或陣列。
•不支援 JavaScript 的 Date、Error、規則表示式或函式表示。

舉個例子來說,下面是個物件實字:

var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};


若使用JSON表示,則是如下:

var json = '{"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}';


若為排版會比較容易觀察:

{
    "name":"Justin",
    "age":35,
    "childs":[
        {
            "name":"hamimi",
            "age":3
        }
    ]
}


JSON.stringify

ECMAScript 5 規範中,如果要從物件建立 JSON 字串,只要使用 JSON.stringify。例如:

var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};

var json = JSON.stringify(obj);

// {"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}
console.log(json);

//{"name":"Justin","age":35}
console.log(JSON.stringify(obj, ['name', 'age']));


JSON.stringify 可以指定第二個引數,若指定陣列,只會針對該陣列轉換 JSON 字串,若指定函式,這個函式可接受物件的特性與值,可以自行決定如何轉換為 JSON 字串。

第一次呼叫指定函式時,鍵為空字串,而值為要被轉換的物件本身,之後逐一以每個特性與值來呼叫函式,傳回值若是數字、字串、布林值,就會被加入 JSON 字串,如果傳回物件,則會遞迴地呼叫指定的函式進行轉換,如果傳回 undefined,該特性就不會被加入 JSON 字串。

例如,上頭的 obj 轉換為 JSON 字串時,不想要有 age 特性的話,可以如下:

var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};

console.log(JSON.stringify(obj, function(key, value) {
    if(key === 'age'){
        return undefined;
    }
    return value;
}));


JSON.stringify 可以指定第三個引數,如果是 1 到 10 的數字,會自動換行並以指定數字作為縮排層次,如果指定字元,就會以指定的字元來進行縮排。例如:

var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};

function replacer(key, value) {
    return key === 'age' ? undefined : value;
}

console.log(JSON.stringify(obj, replacer, 2));


顯示的結果會是兩個空格縮排:

{
  "name": "Justin",
  "childs": [
    {
      "name": "hamimi"
    }
  ]
}


如果物件本身定義有 toJSON 方法,JSON.stringify 會使用 toJSON 傳回的物件來進行 JSON 字串轉換。例如:

var obj = {
    name : 'Justin',
    age : 35,
    toJSON : function() {
        return {
            name : this.name.toUpperCase(),
            age  : this.age
        };
    }
};

// {"name":"JUSTIN","age":35}
console.log(JSON.stringify(obj));


JSON.parse

如果想將 JSON 字串剖析為 JavaScript 物件,可以使用 JSON.parse,例如:

var json = '{"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}';
var obj = JSON.parse(json);

console.log(obj.name); // Justin


每個鍵值被剖析為值之後,可以指定一個函式來決定被剖析後的值如何轉換,傳回的值決定了最後得到的物件上之特性值,如果傳回 undefined,就不會包括該特性。例如:

var json = '{"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}';

var obj = JSON.parse(json, function(key, value) {   
    if(key === 'age'){
        return undefined;
    }
    return value;
});

console.log(obj); // { name: 'Justin', childs: [ { name: 'hamimi' } ] }


如果是沒有內建 JSON 支援的平台(像是一些舊瀏覽器),可以在 Introducing JSON 下載 json2.js,用以獲得上述的相關 JSON 方法。

作者: jehovahcloud    時間: 2017-2-15 08:48 PM

分享一個 JSON 在 PHP 裡處理時容易中招的點,主要是因為 php 太神了,所以才會出現這東西...

php 將 array 轉成 json 基本上會照下面法則走。
1. json_encode([ 'prop1' => 1, 'prop2' => 2]) 會輸出 { "prop1":1, "prop2":2 }
2. json_encode([])  還是會輸出 []

因為 php 的 array 很方便,有時候大家會習慣用 array 來操作,這種時候就很容易因為輸入跟輸出的轉換會造成錯誤。舉例來說,如果傳入的資料是下面的資料
$input = '{ "a":1, "b":2, "c":{ "invalid":"str" } }';

我們有時候會習慣用下面的方法來將資料解析成 php array。
$data = json_decode( $input, true );

然後我們把不要的資料過濾掉
unset($data["c"]["invalid"]);

接著一般來說會用下面方式把資料轉回 json 要送回去給 js。
$output = json_encode($data);

這個時候 js 可能就爆開了!!!因為... $output 裡面會變成下面的 JSON 格式。
$output = '{ "a":1, "b":2, "c":[] }'

本來放物件的地方變成放 array...
這東西的解決方法要就在輸出時多加 if 來檢查,不然就是在 json_decode 時不要強制把 object 轉乘 assoc array,也就是 json_decode 第二個參數保持預設的 false。

然後在程式碼中不要偷懶,已經知道是 object 就保持 object,array 的就確保他是 array。
作者: jehovahcloud    時間: 2017-2-15 08:53 PM

另外再講一個也很容易中招的東西...

拿下面資料舉例:
$data = [ "item1", "item2", "item3" ];

一般來說,json_encode($data) 時會是很正常的下面的值
[ "item1", "item2", "item3" ]

但是如果在操作時,我們偶而會把某個項目用下面的方法拿掉拿掉。
unset($data[1]);

這個時候就很神奇了...
json_encode($data) 會輸出 { "0":"item1", "3":"item3" }

因為 php 存 array 的方式的問題會造成 json_encode 在判斷 array 時出問題...
所以這種狀況要用下面的方式處理。
json_encode(array_values($data))

php 才會確保輸出 [ "item1", "item3" ]


不然你在 js 以為是 array 的被強制變成 object...
這樣 js 那邊就超級容易爆炸的,而且很可悲的是...這種 bug 通常要找很久....




歡迎光臨 伊莉討論區 (http://www1.eyny.com/) Powered by Discuz!