主頁 > 企業開發 > JSON.parse 和 JSON.stringify 詳解

JSON.parse 和 JSON.stringify 詳解

2022-01-01 06:11:35 企業開發

JSON格式,(簡寫JavaScript Object Notation),是一種用于資料交換的文本格式,書寫簡單,
基于JavaScript原生語法,能夠序列化物件、陣列、數值、字串、布林值和 null,

在ES5中,增加了一個JSON物件,專門用來處理JSON格式的資料,
JSON是一個物件,但只有兩個方法:parsestringify,不能作為建構式,也無屬性,

typeof JSON === 'object'

JSON.parse

JSON.parse() 用來決議JSON字串,得到對應的JavaScript值或物件,

JSON.parse('{}') // {}
JSON.parse('true') // true
JSON.parse('null') // null

JSON.parse 語法

JSON.parse(text[, reviver])
  • text:要被決議成的字串,
    如果傳入數字則會轉換成十進制數字輸出,
    如果傳入布林值則直接輸出,
    如果傳入null則輸出null,
    不支持其他型別的值,否則報錯,
  • reviver: 可選,轉換器, 可以用來修改決議生成的原始值,

回傳值: JavaScript物件/值, 對應給定JSON文本的物件/值,

reviver 引數

reviver函式,用于轉換處理決議到的JavaScript值,處理完后回傳最終的結果,

轉換程序:

  • 決議的值本身和它可能包含的所有屬性,按照一定遍歷順序分別呼叫reviver函式,屬性名和值作為引數兩個引數 keyvalue 傳入,
    遍歷順序:按照層級,從內往外遍歷,最終到達最頂層,則是決議值本身,
  • reviver回傳undefined,則洗掉該物件,如果回傳了其他值,則該值會成為當前屬性的新值,
  • 當遍歷到最頂層時,因為沒有屬性了,引數key是空字串'',引數value則是當前決議值,

對于reviver函式的兩個引數 keyvalue,不同的資料型別:

  • 基本值型別資料(string、number、boolean)和null,以及空物件{}和空陣列[]
    則key是空字串,value是對應決議值,
    因為已經是最頂層,并沒有別的屬性,
  • Object物件:
    則key和value都存在,與屬性名和值各自對應,
    最頂層會回傳一個引數key為空的值,
  • 陣列:
    key對應陣列索引,value對應元素值,
    最頂層會回傳一個引數key為空的值,

基本型別的轉換:

JSON.parse('5', function (key, value) {
  console.log(`key:${key}, value:${value}`)
})
// key:, value:5
JSON.parse('null', function (key, value) {
  console.log(`key:${key}, value:${value}`)
})
// key:, value:null
JSON.parse('{}', function (key, value) {
  console.log(`key:${key}, value:`, value)
})
// key:, value:{}

Object物件和陣列:

JSON.parse('[1, 2]', function (key, value) {
  console.log(`key:${key}, value:`, value)
})
// key:0, value: 1
// key:1, value: 2
// key:, value: (2) [empty × 2]

JSON.parse('{ "user": "張三", "info": { "age": 25, "sex": 1 } }', function (key, value) {
  console.log(`key:${key}, value::`, value)
})
// key:user, value:: 張三
// key:age, value:: 25
// key:sex, value:: 1
// key:info, value:: {}
// key:, value:: {}

資料處理:

JSON.parse('[1, 2]', function (key, value) {
  if(key === '') {
    return value
  }
  return value + 3
})
// [4, 5]

JSON.parse 特性

在決議JSON字串的時候,需要注意到JSON格式的一些規范,不然就容易報錯,
JSON資料對值的型別和格式,都有嚴格的規定,具體的規則如下:

  1. 該方法使用字串型別JSON格式資料,
    該方法也支持數字、布林值和null三個型別的值,轉換出對應的字面值,
    不支持其他型別,
JSON.parse('"中國"')
// '中國'
JSON.parse(null) // null
JSON.parse(111.) // 111
JSON.parse(0x12) // 18
JSON.parse(true) // true
JSON.parse([])
// Uncaught SyntaxError: Unexpected end of JSON input
  1. 字串必須使用雙引號,不能使用單引號,
JSON.parse('"String"')
// 'String'
JSON.parse('\'String\'')
// Uncaught SyntaxError: Unexpected token ' in JSON at position 0
  1. 只支持十進制的字串,但小數點后必須跟上數字,
JSON.parse('111') // 111
JSON.parse('0x12')
// Uncaught SyntaxError: Unexpected token x in JSON at position 1
JSON.parse('111.232') // 111.232
JSON.parse('111.')
// Uncaught SyntaxError: Unexpected end of JSON input
  1. 不能使用undefined、Symbol和BigInt,數字也不支持NaN、Infinity和-Infinity,都會報錯,
JSON.parse(undefined)
// Uncaught SyntaxError: Unexpected token u in JSON at position 0
JSON.parse(Symbol())
// Uncaught TypeError: Cannot convert a Symbol value to a string
JSON.parse('12n')
// Uncaught SyntaxError: Unexpected token n in JSON at position 2
  1. 復合型別,只能是:[]{} 這樣的字面量,
    不能使用物件建構式,因為會當作執行陳述句,不支持,
    不能使用Object和Array,也不能是函式、RegExp物件、Date物件、Error物件等,
JSON.parse('[]')
// []
JSON.parse('Object()')
// Uncaught SyntaxError: Unexpected token O in JSON at position 0
  1. 物件的屬性名必須使用雙引號,
JSON.parse('{"key": 1 }')
// {key: 1}
JSON.parse('{key: 1 }')
// Uncaught SyntaxError: Unexpected token k in JSON at position 1
  1. 陣列或物件最后一個成員的后面,不能加逗號,
JSON.parse('[1, 2, 3, 4, ]')
// VM2771:1 Uncaught SyntaxError: Unexpected token ] in JSON at position 13
JSON.parse('{"key" : 1, }')
// VM2779:1 Uncaught SyntaxError: Unexpected token } in JSON at position 12
  1. 支持unicode轉義,
JSON.parse('{"\u0066":333}')
// {f: 333}
  1. 部分控制字符、轉義字符不支持,如'\n'、'\t'等,
JSON.parse('"\n"')
// Uncaught SyntaxError: Unexpected token 

決議的其他方法

將json字串轉成json物件(js物件值),還可以使用其他方法,但是非安全代碼,

  const str = '{"name":"json","age":18}'
  const json = JSON.parse(str)
  const json = eval("(" + str + ")")
  const json = (new Function("return " + str))()

JSON.stringify

JSON.stringify() 將一個JavaScript物件或值轉換為JSON格式字串,

JSON.stringify 語法

JSON.stringify(value[, replacer [, space]])
  • value:將要序列化成 一個 JSON 字串的JavaScript物件或值,
  • replacer 可選,用于處理將要序列化的值,
  • space 可選,指定縮進用的空白字串,用于美化輸出,

回傳值: 一個表示給定值的JSON格式字串,

replacer引數

replacer 引數可以以下三種情況:

  1. 如果是null、undefined或其他型別,則被忽略,不做處理;
JSON.stringify({key: 'json'}, null, null) // '{"key":"json"}'
JSON.stringify({key: 'json'}, true) // '{"key":"json"}'
  1. 如果是一個陣列,則只有包含在這個陣列中的屬性名,才會最終被序列化到結果字串中;
    只對物件的屬性有效,對陣列無效,
const obj = {
  json: 'JSON',
  parse: 'PARSE',
  stringify: 'STRINGIFY'
}
JSON.stringify(obj, ['parse', 'stringify'])
// '{"parse":"PARSE","stringify":"STRINGIFY"}'
  1. 如果是一個函式,被序列化的值的每個屬性都會經過該函式的轉換和處理;

處理程序:

  • 函式有兩個引數,屬性名(key)和屬性值(value),都會被序列化;
  • 第一次呼叫時,key為空字串,value則為需要序列化的整個物件;
  • 第二次處理時,會把第一次的的結果傳過來,后續的每一次的處理都將接收上一次處理的結果;
  • 后面,將依次處理每個屬性名和屬性值,完成后回傳,
JSON.stringify({ json: 1, stringify: { val: 'rr'} }, (key, value) => {
  console.log(`key:${key},value:`, value)
  return value
}) 
// key:,value: {json: 1, stringify: {…}}
// key:json,value: 1
// key:stringify,value: {val: 'rr'}
// key:val,value: rr
// '{"json":1,"stringify":{"val":"rr"}}'

value的型別處理:

  • 如果回傳基本型別字串、數字、布林值、null,則直接被添加到序列化后的JSON字串中;
  • 如果回傳其他物件,則會在后續依次序列化該物件的屬性,如果是函式則不作處理;
  • 如果回傳或undefined,則不會輸出該屬性,
  • 序列化陣列時,如果value回傳undefined或者一個函式,將會被null取代,
JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
  if (typeof value =https://www.cnblogs.com/jimojianghu/p/=='number') {
    return 'ss'
  }
  return value
}) 
// '{"json":"ss","stringify":"rr"}'

JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
  if (typeof value =https://www.cnblogs.com/jimojianghu/p/=='number') {
    value = https://www.cnblogs.com/jimojianghu/p/undefined
  }
  return value
}) 
//'{"stringify":"rr"}'

下面示例,是回傳物件值時的處理:

JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
  if (typeof value =https://www.cnblogs.com/jimojianghu/p/=='object') { // 第一次回傳整個物件時,型別是object
    return { parse: 'dd' }
  }
  return value
}) 
'{"parse":"dd"}'

space 引數

space 引數用來控制結果字串里面的間距,美化輸出,可以輸入的值有以下三種情況:

  • 如果是一個數字, 序列化時,每一層級比上一層級多縮進對應數字值的空格,范圍在 1 - 10,即最小1個最大10個空格;
  • 如果是一個字串,序列化時,該字串會添加在每行前面,每一層級比上一層級多縮進該字串,最多是個字符,超過則截取字串;
  • 如果是null、undefined或其他型別,則被忽略,不做處理,
JSON.stringify({key: 'json'}, null, 2)
// '{\n  "key": "json"\n}'
JSON.stringify({key: 'json', list: { str: 'str' } }, null, '|-')
// '{\n|-"key": "json",\n|-"list": {\n|-|-"str": "str"\n|-}\n}'
JSON.stringify({key: 'json'}, null, null)
// '{"key":"json"}'

JSON.stringify 特性

  1. 基本型別值字串、數字、布林值,以及String、Boolean、Number物件值,都會轉成原始值字串輸出,
JSON.stringify(333) // '333'
JSON.stringify(true) // 'true'
JSON.stringify(new String('333')) //'"333"'
JSON.stringify(Boolean(true)) // 'true'
  1. 基本型別的字串,轉換結果會帶雙引號,
    因為在還原時,雙引號會讓JavaScript知道是字串,而不是變數,
JSON.stringify('json') === 'json' // false
JSON.stringify('json') === '"json"' // true
  1. undefined、函式、symbol以及XML物件:
  • 出現在Object物件中時,會被忽略;
  • 出現在陣列中時,會被序列化成null;
  • 單獨出現時,會回傳undefined,
JSON.stringify(Symbol()) // undefined
JSON.stringify([Symbol(), Math.abs, undefined]) // '[null,null,null]'
JSON.stringify({ [Symbol()]: Math.abs, key: undefined }) // '{}'
  1. NaN、Infinity和-Infinity等值,還有null,都會被序列化成null,
JSON.stringify(null) // 'null'
JSON.stringify(NaN) // 'null'
  1. Object物件,以及Map/Set/WeakMap/WeakSet等復合型別物件,序列化時會忽略物件的不可遍歷屬性,
const obj = {}
Object.defineProperties(obj, {
  'json': { value: 'JSON', enumerable: true },
  'stringify': { value: 'STRINGIFY', enumerable: false }
})
JSON.stringify(obj)
// '{"json":"JSON"}'
  1. 以symbol為屬性名的屬性將被忽略,
JSON.stringify({[Symbol()]: 333}) // '{}'
  1. 除了陣列,其他物件的屬性在序列化時,順序可能會亂,
const a = { '1': 911, 'r': 822, '11': 9922}
JSON.stringify(a)
// '{"1":911,"11":9922,"r":822}'
  1. 轉換的物件如果定義了 toJSON() 方法,則該方法的回傳值就是轉換物件的序列化結果,
    該程序會忽略其他屬性,
const a = { key: 'json' }
a.toJSON = () => 'JSON'
JSON.stringify(a)
// '"JSON"'
  1. RegExp物件、Error物件都會序列化為空物件字串,
JSON.stringify(/\d/) // "{}"
JSON.stringify(new Error())  // "{}"

想要序列化相應物件,需要設定實作toJSON方法才行,

RegExp.prototype.toJSON = RegExp.prototype.toString
JSON.stringify(/\d/) // '"/\\\\d/"'
  1. Date物件已經定義了toJSON(),并將其轉換為string字串,因此可被序列化,
    Date.toISOString()
JSON.stringify(new Date())
// '"2021-12-31T02:24:05.477Z"'
  1. 回圈參考的物件執行此方法,會拋出錯誤,
    物件之間相互參考,形成無限回圈,
const a = {}
a.key = a
JSON.stringify(a)
// Uncaught TypeError: Converting circular structure to JSON
  1. 轉換BigInt型別的值會拋出TypeError錯誤,
    BigInt值不能JSON序列化
JSON.stringify(12n)
// Uncaught TypeError: Do not know how to serialize a BigInt
  1. 更好的支持unicode轉義符
const a = {'\u0066': 333}
JSON.stringify(a)
// '{"f":333}'

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/399517.html

標籤:JavaScript

上一篇:ELK集中化日志解決方案——看這一篇全搞定

下一篇:Reflection 基礎知識(一)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more