摘要:會(huì)對(duì)對(duì)象中的每一個(gè)鍵值對(duì)調(diào)用函數(shù),然后會(huì)使用其返回值,作為格式化后的值,比如使每個(gè)屬性的值遞增函數(shù)在省略敏感數(shù)據(jù)時(shí),十分有用。如果它發(fā)現(xiàn)方法,會(huì)調(diào)用它,然后將它的返回值替換格式化后的值,比如方法可以返回任意的值,包括對(duì)象基礎(chǔ)類型,或者。
http://thecodebarbarian.com/t...寫在前面
JSON.stringfy()是將一個(gè) JavaScript 對(duì)象轉(zhuǎn)化為 JSON 格式字符串的標(biāo)準(zhǔn)方式。許多 JavaScript 框架在其內(nèi)部,都會(huì)使用 JSON.stringify():Express的 res.json()、Axios的 post,以及webpack stats,它們都調(diào)用了 JSON.stringify() 方法,并包含錯(cuò)誤案例。
譯者注:這篇文章已經(jīng)被翻譯過多次了,但是我覺得寫的太好了,所以就再翻譯一次吧,當(dāng)作是加深印象。
簡單入門所有的現(xiàn)代 JavaScript 運(yùn)行時(shí)都支持 JSON.stringify(),甚至 IE8 都支持它。下面是一個(gè)將簡單對(duì)象轉(zhuǎn)化為 JSON 的例子:
const obj = { answer: 42 }; const str = JSON.stringify(obj); str; // "{"answer":42}" typeof str; // "string"
你可能經(jīng)常看到 JSON.stringify() 和 JSON.parse() 一起配合使用的場景,就像下面的代碼一樣,這種模式是實(shí)現(xiàn)深拷貝的方式之一:
const obj = { answer: 42 }; const clone = JSON.parse(JSON.stringify(obj)); clone.answer; // 42 clone === obj; // false錯(cuò)誤以及邊界用例
JSON.stringify() 在轉(zhuǎn)化對(duì)象存在循環(huán)引用時(shí),會(huì)拋出錯(cuò)誤。更簡單地說,就是如果一個(gè)對(duì)象有一個(gè)屬性指向它本身,JSON.stringify() 會(huì)拋出錯(cuò)誤,比如:
const obj = {}; // 存在循環(huán)引用的對(duì)象,它指向它本身 obj.prop = obj; // 會(huì)拋出 "TypeError: TypeError: Converting circular structure to JSON" 異常 JSON.stringify(obj);
這是 JSON.stringify() 會(huì)拋出異常的唯一情況,除非你通過聲明自定義的 toJSON() 方法或者 replacer 函數(shù)。盡管如此,你仍然應(yīng)該將 JSON.stringify() 包含在 try/catch 語句中,因?yàn)檠h(huán)引用在實(shí)踐中十分常見。
同時(shí),一些邊界用例下,JSON.stringify() 并不會(huì)拋出錯(cuò)誤,但是你可能卻期望它拋出錯(cuò)誤。比如說,JSON.stringify() 會(huì)將 NaN 和 Infinity 轉(zhuǎn)化為 null:
const obj = { nan: parseInt("not a number"), inf: Number.POSITIVE_INFINITY }; JSON.stringify(obj); // "{"nan":null,"inf":null}"
JSON.stringify() 也會(huì)直接省略那些值為 functions 和 undefined 的屬性,如下:
const obj = { fn: function() {}, undef: undefined }; // 它會(huì)返回空對(duì)象 JSON.stringify(obj); // "{}"格式化
JSON.stringify() 的第一個(gè)參數(shù)是被序列化為 JSON 的對(duì)象。JSON.stringify() 實(shí)際上可以接受 3 個(gè)參數(shù),同時(shí)第三個(gè)參數(shù)被稱作 spaces。spaces 參數(shù)被用于采用一種可以提高可讀性的方式來格式化 JSON 字符串。
你可以傳遞類型為 string 或者 number 的 spaces 參數(shù)。如果 spaces 為 undefined,那么 JSON.stringify() 會(huì)將每個(gè)鍵值放到多帶帶的一行,同時(shí)為其增加正確的縮進(jìn)空格,比如:
const obj = { a: 1, b: 2, c: 3, d: { e: 4 } }; // "{"a":1,"b":2,"c":3,"d":{"e":4}}" JSON.stringify(obj); // { // "a": 1, // "b": 2, // "c": 3, // "d": { // "e": 4 // } // } JSON.stringify(obj, null, " "); // 數(shù)字 2 會(huì)達(dá)到和上面一樣的效果,它代表空格的個(gè)數(shù) JSON.stringify(obj, null, 2);
spaces 字符串不一定非要是空格,雖然通常我們會(huì)使用空格,比如它也可以是下劃線:
// { // __"a": 1, // __"b": 2, // __"c": 3, // __"d": { // ____"e": 4 // __} // } JSON.stringify(obj, null, "__");Replacers
JSON.stringify() 的第二個(gè)參數(shù)是 replacer 函數(shù)。在上文的例子中,它等于 null。JavaScript 會(huì)對(duì)對(duì)象中的每一個(gè)鍵值對(duì)調(diào)用 replacer 函數(shù),然后會(huì)使用其返回值,作為格式化后的值,比如:
const obj = { a: 1, b: 2, c: 3, d: { e: 4 } }; // 使每個(gè)屬性的值遞增 1 // "{"a":2,"b":3,"c":4,"d":{"e":5}}" JSON.stringify(obj, function replacer(key, value) { if (typeof value === "number") { return value + 1; } return value; });
replacer 函數(shù)在省略敏感數(shù)據(jù)時(shí),十分有用。假設(shè)你想要省略所有包含 password 的屬性:
const obj = { name: "Jean-Luc Picard", password: "stargazer", nested: { hashedPassword: "c3RhcmdhemVy" } }; // "{"name":"Jean-Luc Picard","nested":{}}" JSON.stringify(obj, function replacer(key, value) { // 這個(gè)函數(shù)會(huì)被調(diào)用 5 次,這里的 key 依次為: // "", "name", "password", "nested", "hashedPassword" if (key.match(/password/i)) { return undefined; } return value; });toJSON 方法
JSON.stringify() 方法在遍歷對(duì)象的同時(shí),也會(huì)關(guān)注那些擁有 toJSON() 方法的屬性。如果它發(fā)現(xiàn) toJSON() 方法,JSON.stringify() 會(huì)調(diào)用它,然后將它的返回值替換格式化后的值,比如:
const obj = { name: "Jean-Luc Picard", nested: { test: "not in output", toJSON: () => "test" } }; // "{"name":"Jean-Luc Picard","nested":"test"}" JSON.stringify(obj);
toJSON() 方法可以返回任意的值,包括對(duì)象、基礎(chǔ)類型,或者 undefined。如果 toJSON() 返回 undefined,JSON.stringify() 將會(huì)忽略這個(gè)屬性。
很多 JavaScript 模塊使用 toJSON() 來確保序列化復(fù)雜對(duì)象的正確性,比如 Mongoose documents 和 Moment 對(duì)象。
最后JSON.stringify() 是 JavaScript 中較核心的基礎(chǔ)方法。許多庫和框架在其內(nèi)部都使用它,因此,深入的理解它,可以幫助你更好地使用你喜歡的 npm 模塊。比如,你可以在 Express REST API 中利用 toJSON 方法來格式化原生 Date 類型,或者在 Axios 中,能夠正確地通過 HTTP 請求發(fā)送包含循環(huán)引用的對(duì)象。
關(guān)注公眾號(hào) 全棧101,只談技術(shù),不談人生
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/104321.html
摘要:第三章原生函數(shù)有很多原生函數(shù),為基本的數(shù)據(jù)類型值提供了封裝對(duì)象,,,等。我們可以通過來查看所有返回的對(duì)象的內(nèi)置屬性這個(gè)屬性無法直接訪問。這個(gè)符號(hào)能有奇妙的功能,可以視為。通常用來把轉(zhuǎn)換為數(shù)字,用來將轉(zhuǎn)換為字符串,用來將取整。 第三章 原生函數(shù)JS有很多原生函數(shù),為基本的數(shù)據(jù)類型值提供了封裝對(duì)象,String,Number,Boolean等。我們可以通過{}.call.toStri...
摘要:為了體現(xiàn)前后端分離,提高開發(fā)效率的精髓。轉(zhuǎn)發(fā)消息服務(wù)器將收到的來自于發(fā)送方消息中的值作為要轉(zhuǎn)發(fā)的目標(biāo)接收方,在服務(wù)器自身維護(hù)的對(duì)象中找到接收方的這個(gè)連接,然后將發(fā)送方的標(biāo)識(shí)作為轉(zhuǎn)發(fā)給接收方。 背景 簡單的描述一下需求場景:應(yīng)用需要進(jìn)行客戶端到客戶端的通信,websocket 就能很好的進(jìn)行這一操作,目前 網(wǎng)易云信的 IM 等功能也是利用 websocket 進(jìn)行的。 必要性 對(duì)前端開發(fā)...
摘要:業(yè)務(wù)組件模塊化拆分復(fù)用后整體可維護(hù)性也得到了很大提升。先贊一個(gè)當(dāng)然凡事都有相對(duì)的一面,此篇文字就主要記錄自己在項(xiàng)目過程中的一些問題。 原文地址:http://mtmzorro.github.io/201... 項(xiàng)目背景 需要兼容到IE7(根據(jù)數(shù)據(jù)支撐重要說服拋棄IE6) 上個(gè)版本傳統(tǒng) jQuery DOM 開發(fā)模式,經(jīng)過無數(shù)手維護(hù)已經(jīng)慘不忍睹 核心業(yè)務(wù)流程,可維護(hù)性、健壯性要求高 主...
摘要:眾所周知,中值的變化,會(huì)導(dǎo)致組件重新渲染。使用就是為了減少不必要的渲染。此方法就是拿當(dāng)前中值和下一次中的值進(jìn)行對(duì)比,數(shù)據(jù)相等時(shí),返回,反之返回。使用進(jìn)行深拷貝,但是遇到數(shù)據(jù)為和函數(shù)時(shí)就會(huì)錯(cuò)。使用進(jìn)行項(xiàng)目的搭建。 眾所周知,react中props,state值的變化,會(huì)導(dǎo)致組件重新渲染。使用shouldComponentUpdate就是為了減少render不必要的渲染。 本文著重回答以下...
閱讀 1468·2021-09-26 09:55
閱讀 1979·2019-08-30 12:45
閱讀 1137·2019-08-29 11:20
閱讀 3612·2019-08-26 11:33
閱讀 3502·2019-08-26 10:55
閱讀 1748·2019-08-23 17:54
閱讀 2467·2019-08-23 15:55
閱讀 2401·2019-08-23 14:23