JSON 格式與 JavaScript 解析教學範例

JSON

什麼是 JSON?AJAX 與 JSON 又有什麼關係呢!本篇文章將介紹什麼是 JSON 和應用領域以及如何建立 JSON 格式,並以範例說明如何使用 JavaScript 處理 JSON 教學。

簡介

什麼是 JSON

  • JSON (JavaScript 物件表示法)。
  • 一種以純文字為基礎,來儲存和交換簡單結構的輕量級【資料交換格式】(類似 XML)。
  • 獨立於語言。
  • 具有自我描述性,更易於人理解、閱讀和編寫,同時也易於機器解析和生成。
  • JSON 比 XML (可延伸標記式語言) 更小、更快且更易解析。

應用領域

JSON 最開始被廣泛的應用於 Web 的開發,隨著 Web 2.0 的方興未艾,JSON 在 Web 資料傳輸領域占有重要的地位。

JSON 因小巧與瀏覽器內建快速解析支援,因此較適用於網路資料傳輸領域,而目前最常用在 AJAX (非同步的 JavaScript 與 XML 技術) 的資料傳輸。

JSON 與 XML 比較

JSON 與 XML 最大的不同在於 XML 是一個完整的標記語言,而 JSON 不是。這使得 XML 在程式判讀上需要比較多的功夫。主要的原因在於 XML 的設計理念與 JSON 不同。XML 利用標記語言的特性提供了絕佳的延展性 (如 XPath),在資料儲存,擴充功能及高階檢索方面具備對 JSON 的優勢,而 JSON 則由於比 XML 更加小巧,以及瀏覽器的內建快速解析支援,使得其更適用於網路資料傳輸領域。

JSON 格式

字串

JSON 字串可以包含 object (物件) 或 array (陣列) 資料,object 與 array 也可互相包含:

{
    "member": [
        { "name": "Jacky" },
        { "name": "Marry" },        
    ]
}

物件

  • 一個 object 以 { 開始,並以 } 結束,來寫入資料。
  • name 為 string,必須以 "" 括起來。
  • name 與 value 之間使用 : 分隔。
  • 多個 name:value 之間使用 , 分隔。
{ "name": value, "name": value }

陣列

  • 一個陣列以 [ 開始,並以 ] 結束,來寫入資料。
  • 多個 value 之間使用 , 分隔。
[value, value]

object 和 array 的值

object 和 array 可使用的資料型態與值如下:

{ "array": ["string", 10, 1.0, -1, true, false, null] }
JSON 資料型態
資料型態 值 / 說明
英文 中文
object 物件 {}
array 陣列 []
string 字串 "" 括起來的內容 (不可使用單個 '')
number 數值 0-9 的數字組合 (整數、小數或負數)
boolean 布林值 truefalse
null 空值 null

JSON 字串範例

例如一個會員的基本資料,使用 JSON 字串表示如下:

{
     "number": "1020501",
     "name": "小傑",
     "age": 32,
     "sex": "M",
     "interest": [
         "網頁設計",
         "撰寫文章"
     ]
 }

JavaScript 處理 JSON

物件序列化成 JSON 字串

JSON.stringify() 可以將 JavaScript 物件序列化成 JSON 字串:

// JavaScript 物件
var member = {
    "number": "1020501",
    "name": "小傑",
    "age": 32,
    "sex": "M",
    "interest": [
        "網頁設計",
        "撰寫文章"
    ]
};
 
console.log(
    JSON.stringify(member)  // 序列化成 JSON 字串
);
 
/* 輸出:
 
{"number":"1020501","name":"小傑","age":32,"sex":"M","interest":["網頁設計","撰寫文章"]}
 */

JSON.stringify() 方法可指定第二個參數:

  • 如果該參數是一個 function (可接受物件的特性與值,可以自行決定如何轉換為 JSON 字串) 則在序列化過程中,被序列化的值的每個屬性都會經過 function 的轉換和處理,return 值為:
    • numberstringboolean:就會被加入 JSON 字串。
    • object:會遞迴呼叫指定的 function 進行轉換。
    • undefined:該特性就不會被加入 JSON 字串。
  • 如果該參數是一個 array,則只有包含在這個 array 中的屬性名才會被序列為 JSON 字串。
// JavaScript 物件
var member = {
    "number": "1020501",
    "name": "小傑",
    "age": 32,
    "sex": "M",
    "interest": [
        "網頁設計",
        "撰寫文章"
    ]
};
 

// 使用第二個參數 function 方式,排除 age 特性不被序列為 JSON 字串
console.log(
    JSON.stringify(member, function(key, value) {
        if (key === "age") return undefined;
 
        return value;
    })
);
 
/* 輸出:
 
{"number":"1020501","name":"小傑","sex":"M","interest":["網頁設計","撰寫文章"]}
 */


// 使用第二個參數 array 方式,指定要被序列為 JSON 字串的特性
console.log(
    JSON.stringify(member, ["number", "name"])
);
 
/* 輸出:
 
{"number":"1020501","name":"小傑"}
 */

JSON.stringify() 方法可指定第三個參數,來控制結果字串的縮排間距,並會自動換行:

  • 如果是一個【數值】則代表有多少空格 (上限 10、小於 1 則沒有空格)。
  • 如果是一個【字串】則該字串將被作為空格。
// JavaScript 物件
var member = {
    "number": "1020501",
    "name": "小傑",
    "age": 32,
    "sex": "M",
    "interest": [
        "網頁設計",
        "撰寫文章"
    ]
};
 

// 使用第三個參數【數值】方式指定縮排
console.log(
    JSON.stringify(member, null, 2)
);
 
/* 輸出:
 
{
  "number": "1020501",
  "name": "小傑",
  "age": 32,
  "sex": "M",
  "interest": [
    "網頁設計",
    "撰寫文章"
  ]
}
 */


// 使用第三個參數【字串】方式指定縮排
console.log(
    JSON.stringify(member, null, "t")
);
 
/* 輸出:

{
t"number": "1020501",
t"name": "小傑",
t"age": 32,
t"sex": "M",
t"interest": [
tt"網頁設計",
tt"撰寫文章"
t]
}
 */

JSON 字串解析成 JavaScript 物件

JSON.parse() 方法

JSON.parse() 方法可以將 JSON 字串解析成 JavaScript 物件,這樣就可使用 JavaScript 進行操作了:

// 宣告字串須使用 '' 括起來,否則就會變成是 JavaScript object 了
// 如在不同行必須在每行結尾處加上 \,否則會產生 SyntaxError
var jsonString = '{ \
    "number": "1020501", \
    "name": "小傑", \
    "age": 32, \
    "sex": "M", \
    "interest": [ \
        "網頁設計", \
        "撰寫文章" \
    ] \
}';
 
// 將 JSON 字串解析成 JavaScript 值,這樣就可使用 JavaScript 進行操作了
var member = JSON.parse(jsonString);
 
// 取得物件的指定值
console.log(
    member.name + ', ' +
    member.interest[0]
);
 
/* 輸出:
 
小傑, 網頁設計
 */

JSON.parse() 方法可指定第二個參數 function 用來轉換解析出的屬性值,return 的值決定最後在物件上的特性值;若 return 的值為 undefined,就不會包括該特性:

// 宣告字串須使用 '' 括起來,否則就會變成是 JavaScript Object 了
// 如在不同行必須在每行結尾處加上 \,否則會產生 SyntaxError
var jsonString = '{ \
    "number": "1020501", \
    "name": "小傑", \
    "age": 32, \
    "sex": "M", \
    "interest": [ \
        "網頁設計", \
        "撰寫文章" \
    ] \
}';
 
// 使用第二個參數 function 方式,排除 age 特性不被包括在物件
var member = JSON.parse(jsonString, function(key, value) {
    if (key === "age") return undefined;
 
    return value;
});
 
// 取得物件
console.log(member);
 
/* 輸出:
 
Object {number: "1020501", name: "小傑", sex: "M", interest: ["網頁設計", "撰寫文章"]}
 */

eval() 函式

eval() 函式可以將一個 JavaScript 代碼字串求值成特定的物件。字串前後須加上刮號 eval("(" + string + ")"),用來告知 Javascript 這是個物件描述,而不是要執行的 statement:

// 宣告字串須使用 '' 括起來,否則就會變成是 JavaScript object 了
// 如在不同行必須在每行結尾處加上 \ 告知這是接續下一行,否則會產生 SyntaxError
var jsonString = '{ \
    "number": "1020501", \
    "name": "小傑", \
    "age": 32, \
    "sex": "M", \
    "interest": [ \
        "網頁設計", \
        "撰寫文章" \
    ] \
}';
 
// 使用 eval() 將字串求值成特定的物件 (字串前後須加上刮號,用來告知這不是要執行的 statement),這樣就可使用 JavaScript 進行操作了
var member = eval("(" + jsonString + ")");
 
// 取得物件的指定值
console.log(
    member.name + ', ' +
    member.interest[0]
);
 
/* 輸出:
 
小傑, 網頁設計
 */

走訪 (遍歷) JavaScript object 和 array

個別使用 JavaScript for() 與 jQuery each() 兩種方式,在走訪(遍歷)時,將資料帶入 HTML table (表格)。

使用 JavaScript for()

HTML:

<table class="for-table" border="1">
    <thead>
        <tr>
            <th>姓名</th>
            <th>年齡</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>

JavaScript:

var json = [{ "name": "小傑", "age": 32 },
            { "name": "小明", "age": 28 }];
var forTable = document.querySelector('.for-table tbody');
 
for (var i = 0, len = json.length; i < len; i++) {
    forTable.innerHTML += 
        '<tr>' +
            '<td>' + json[i].name + '</td>' +
            '<td>' + json[i].age + '</td>' +
        '</tr>';
}
JavaScript for() 輸出 JSON 資料到 HTML table
姓名 年齡
小傑 32
小明 28

使用 jQuery each()

HTML:

<table class="each-table" border="1">
    <thead>
        <tr>
            <th>姓名</th>
            <th>年齡</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

JavaScript:

var json = [{ "name": "小傑", "age": 32 },
            { "name": "小明", "age": 28 }];
var eachTable = $('.each-table tbody');
 
$.each(json, function(index, element) {
    eachTable.append(
        '<tr>' +
            '<td>' + element.name + '</td>' +
            '<td>' + element.age + '</td>' +
        '</tr>');
});
jQuery each() 輸出 JSON 資料到 HTML table
姓名 年齡
小傑 32
小明 28

參考

在〈JSON 格式與 JavaScript 解析教學範例〉中有 3 則留言

  1. 您好,我在cmd可順利的將json物件內容作換行,結果如下
    [
    {
    "booktitle": "Leading",
    "bookid": "56353",
    "bookauthor": "Sir Alex Ferguson"
    },
    {
    "booktitle": "How Google Works",
    "bookid": "73638",
    "bookauthor": "Eric Smith"
    },
    {
    "booktitle": "The Merchant of Venice",
    "bookid": "37364",
    "bookauthor": "William Shakespeare"
    }
    ]
    PS D:WorkspaceExcel2JsonTestexcel-to-json-in-Node.js> node app.js
    running on 3000...
    uploadsfile-1513237256061.xlsx
    [
    {
    "booktitle": "Leading",
    "bookid": "56353",
    "bookauthor": "Sir Alex Ferguson"
    },
    {
    "booktitle": "How Google Works",
    "bookid": "73638",
    "bookauthor": "Eric Smith"
    },
    {
    "booktitle": "The Merchant of Venice",
    "bookid": "37364",
    "bookauthor": "William Shakespeare"
    }
    ]

    但是要在網頁頁面呈現時,用相同的方卻無法換行,得到的結果如下
    "[n {n "booktitle": "Leading",n "bookid": "56353",n "bookauthor": "Sir Alex Ferguson"n },n {n "booktitle": "How Google Works",n "bookid": "73638",n "bookauthor": "Eric Smith"n },n {n "booktitle": "The Merchant of Venice",n "bookid": "37364",n "bookauthor": "William Shakespeare"n }n]"

    請問造成上述結果的原因為何?

    • 1. 因為換行就是以符號 n 表示,不用特別換行。
      2. 盡量別自行串接 JSON、XML 等等資料交換格式,建議使用程式預設提供的函數,如 PHP 就有提供 json_encode() 與 json_decode() 將陣列編、解碼成 JSON,方便又能減少出錯率。

    • 你最后的JSON格式好像有问题?
      JSON虽然非常好用,但是也有一个缺点,就是比较长的时候格式容易出错而且不好排查,出现了问题可以先看看JSON本身的格式是不是出现了问题
      你可以用一些在线工具排查 https://www.jsonformatting.com/

發表留言