入门魔法 - 了解 JSON 格式及内建方法

前情提要

前几天帮艾草整理了爱情灵药秘方。

「咦,爱情灵药的秘方也太简单了吧,我还以为会很特别呢?」

艾草:「NoNoNo! 你一定是误以为爱情灵药是让人爱上你的那种酷东西吧~不要用狭隘的思想禁锢了它,爱情灵药的目的是为了让你喝到能爱上 J 个人森唷 (*≧▽≦)」

「好像有道理,但你根本只是为了凑出 JSON 的发音吧!!!造句不是这样的啦,你的小学老师在哭了!」

艾草:「既然都发现了,来学习 JSON 罗 ~」


(艾草心里 os 只要自己不尴尬,尴尬的就是别人了)


JSON

首先让我们来了解 JSON 格式的基本资料吧,以下引用至 MDN:

JavaScript Object Notation (JSON) 为将结构化资料 (structured data) 呈现为 JavaScript 物件的标准格式,常用於网站上的资料呈现、传输 (例如将资料从服务器送至用户端,以利显示网页)。

了解完 JSON 的基本资料後,让我们来看看 JSON 格式到底长怎样:

[{
    "年度": "2020",
    "地区别": "屏东县",
    "花卉类别": "切花",
    "花卉种类": "菊花",
    "种植面积": "1.78",
    "每公顷平均收获量": "19152.247",
    "收获量": "34.091"
}]

以上范例程序码取自政府资料开放平台-台湾地区花卉生产概况:https://data.gov.tw/dataset/9682

是不是看起来跟物件根本一模一样呀,但 JSON 格式的属性名称也要用双引号包覆起来。

接下来介绍 JavaScript 内建的 JSON 格式方法。


JSON 格式内建方法

JSON.stringify()

JSON.stringify() 可以将 JavaScript 的值转换为 JSON 的字串,我们可以将想转换格式的值,当成参数传入,范例如下:

let obj = {
	key:'value'
};
console.log(JSON.stringify(obj))//"{"key":"value"}"

可以看到印出的资料 key 外层也会透过引号包覆起来。

JSON.stringify() 可以带入两个参数,分别为:

  • replacer
  • space

replacer 可以是函式,可以透过此函式把自己不想转成字串的值,过滤掉,可以带入两个参数分别对应 key 、 value ,范例如下:

function replacer(key, value) {
  if (typeof value === "number") {
    return undefined;
  }
  return value;
}

let obj = {
  key: "value",
  myName: "shannon",
  pet: "bird",
  age: 18
};

console.log(JSON.stringify(obj, replacer));
//"{"key":"value","myName":"shannon","pet":"bird"}"

像这样符合条件的部分透过 return 回传 undefined ,而结果为 undefined 的值则不会被转成字串。

而第二个参数 space ,可以拿来放入空格,提升 JSON 字串的可视度,此参数可以带入空字串或数字,而数字最多可以带入到 10 ,表示 10 个空格,replacer 参数如果不需使用时,记得带入 null ,范例如下:

let obj = {
  key: "value",
};

console.log(JSON.stringify(obj, null , 10));

显示结果:

https://ithelp.ithome.com.tw/upload/images/20210924/20139066mCPATXWNUF.png

既然我们介绍到如何转成 JSON 字串,接下来来聊聊如何把它变回物件格式吧!

JSON.parse()

JSON.parse() 可以把被我们转成 JSON 字串格式的物件,恢复成物件格式,使用方式如下:

let obj = {
  key: "value",
};
let newObj = JSON.stringify(obj);
console.log(newObj)
console.log(JSON.parse(newObj))

将想要转回来的物件当成参数传进去後,就可以罗!

显示结果:

https://ithelp.ithome.com.tw/upload/images/20210924/20139066l3FlvFbpWP.png

显示结果第一个为 JSON 字串格式,第二个为转回来的物件格式。

当然这方式不限於物件,你也可以丢入其他 JSON 字串进去唷!

JSON.parse() 可以额外传入一个参数:reviver ,reviver 可以是函式,该函式可以带入两个参数,分别代表 key 、value ,除了可以透过 reviver 将不想转回原本值的 JSON 字串过滤掉外,也可以透过 reviver 函式更改值,范例如下:

let obj = {
  key: "value",
  myName:"shannon"
};
let newObj = JSON.stringify(obj);

console.log(JSON.parse(newObj,function(key,value){
  if ( value === 'shannon') {
    return "Tom";
  }
  return value;
}))

显示结果:

https://ithelp.ithome.com.tw/upload/images/20210924/20139066xeRYgFv8rc.png

总结

  • JSON 格式属性名称 key 也要透过双引号包覆起来
  • JSON.stringify() 可以将 JavaScript 的值转换为 JSON 字串,可带入两个参数:
    • replacer 可带入函式,透过该函式过滤不想转成 JSON 字串的值
    • space 可带入空字串或数字,可於 JSON 字串放入空格
  • JSON.parse() 可以将 JSON 字串转回物件格式,可带入一个参数:
    • reviver 可带入函式,透过该函式过滤不想转回原本格式的值

小练习

1.此为政府资料开放平台关於电影的其中一笔 JSON 资料,请参考程序码选出错误叙述的选项

let data = [{
    "version": "1.4",
    "UID": "5fea2cd5d083a300681e9b6c",
    "title": "趴趴熊亲子电影院(9月4场) ",
    "category": "8",
    "showInfo": [
        {
            "time": "2021/09/01 13:30:00",
            "location": "台中市雾峰区大同路8号",
            "locationName": "台中市立图书馆雾峰以文分馆",
            "onSales": "N",
            "price": "",
            "latitude": "24.0615719",
            "longitude": "120.699002",
            "endTime": "2021/09/30 16:00:00"
        }],
    "showUnit": "(不分国籍)本活动无实体展演者",
    "sourceWebName": "全国艺文活动资讯系统",
    "startDate": "2021/09/01",
    "endDate": "2021/09/30",
    "hitRate": 181
}
]

A 如果要取出 "趴趴熊亲子电影院(9月4场) " 可以透过 data[0].title 的方式
B 如果要取出 "台中市立图书馆雾峰以文分馆" 可以透过 data[0].showInfo.locationName 的方式
C 如果要取出 "endTime" 属性的值,可以透过 data[0].showInfo[0]['endTime'] 的方式
D 如果要取出 181 ,可以透过 data[0]['hitRate'] 的方式

解答:选项 B 应该改成 data[0].showInfo[0].locationName ,因为 showInfo 值为阵列,遇到阵列要透过 [] 中括号并放入阵列索引值,取出第 0 笔值後,在透过点记法选取对应的属性名称

2.请问以下叙述何者错误?
A JSON 格式的属性需要透过双引号包覆起来
JSON.stringify() 参数 replacer 可以为函式,可透过该函式过滤不想转字串的值C JSON.parse() 可以将 JSON 字串格式转回物件
JSON.stringify() 参数 replacer 函式内回传为 null 的值不会被转成字串

解答:选项 D 应该将 null 改成 undefined


参考文献

JavaScript 必修篇 - 前端修练全攻略(六角学院)
JavaScript 全攻略:克服 JS 的奇怪部分( Udemy )
https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/Objects/JSON
https://medium.com/itsems-frontend/javascript-json-stringify-and-json-parse-7a1251d3824c


<<:  前端工程师也能开发全端网页:挑战 30 天用 React 加上 Firebase 打造社群网站|Day25 阻挡会员路由

>>:  正视自己的缺点

Rust-30天的心得

分享一下这30天从无到有的学习下来的一点点心得 先说一下为什麽要学习Rust是因为最近比较红之外还有...

【第二十五天 - Floyd-Warshall 题目分析】

先简单回顾一下,今天预计分析的题目: 题目连结:https://leetcode.com/prob...

【前端效能优化】Lighthouse 网站效能检测工具

Lighthouse 一款在 Google Chrome 上安装的扩充套件,用来检测网站的效能,Li...

Angular+Spring Boot API 处理股市资料-前言+认识Spring Boot(Day1)

我与Spring Boot的相识,在那堂讲述SSH架构配置课程後,依稀记得那是一个阳光灿烂的午後,我...

Day 30 | 完赛感言

连续30天发文,一开始觉得很漫长,但没想到很快的就来到了尾声! 透过这个比赛,学到了许多东西(虽然听...