成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

你不知道的 JSON.stringify!!!

開發 前端
JSON.stringify是我們經常用到的的一個方法,它主要作用是將 JavaScript 值和對象轉換為字符串。

[[441493]]

JSON.stringify是我們經常用到的的一個方法,它主要作用是將 JavaScript 值和對象轉換為字符串。如:

  1. JSON.stringify({ foo: "bar" }); 
  2. // => '{"foo":"bar"}' 
  3.  
  4. JSON.stringify(123); 
  5. // => '123' 

但是JS 的許多地方都有問題,這個函數也不例外。我們可能會想象一個叫做 "stringify "的函數總是返回一個字符串......但它并沒有!

例如,如果你嘗試 stringify undefined,它返回 undefined ,而不是一個字符串。

  1. JSON.stringify(undefined); 
  2. // => undefined 

接下來,我將分兩部分講:

  • 列舉 JSON.stringify 不返回字符串的情況
  • 我們將如何避免這些陷阱

什么時候 JSON.stringify 不返回字符串?

undefined、任意的函數以及 symbol 值,在序列化過程中會被忽略(出現在非數組對象的屬性值中時)或者被轉換成 null(出現在數組中時)。函數、undefined 被單獨轉換時,會返回 undefined。

對包含循環引用的對象(對象之間相互引用,形成無限循環)執行此方法,會拋出錯誤

我認為 JSON.stringify 能夠返回字符串以外的東西是挺驚訝的。但在6種情況下,它可以返回undefined:

試圖在頂層對 undefined 進行序列化,會返回 undefined。

  1. JSON.stringify(undefined); 
  2. // => undefined 

嘗試序列化函數也會返回 undefined。對于常規函數、箭頭函數、異步函數和生成器函數都是如此。

  1. JSON.stringify(function foo() {}); 
  2. // => undefined 
  3.  
  4. JSON.stringify(() => {}); 
  5. // => undefined 
  6.  
  7. function bar() {} 
  8. bar.someProperty = 123; 
  9. JSON.stringify(bar); 
  10. // => undefined 

嘗試序列化symbol 也會返回 undefined。

  1. JSON.stringify(Symbol("computers were a mistake")); 
  2. // => undefined 

在瀏覽器中,試圖序列化被廢棄的document.all 也會返回 undefined。

  1. // => undefined 

這只影響到瀏覽器,因為document.all在其他環境中是不可用的,比如Node。

帶有 toJSON 函數的對象將被運行,而不是試圖正常地序列化它們。但是如果 toJSON 返回上面的一個值,試圖在頂層序列化它將導致 JSON.stringify 返回undefined。

  1. JSON.stringify({ toJSON: () => undefined }); 
  2. // => undefined 
  3.  
  4. JSON.stringify({ ignored: true, toJSON: () => undefined }); 
  5. // => undefined 
  6.  
  7. JSON.stringify({ toJSON: () => Symbol("heya") }); 
  8. // => undefined 

你可以傳遞第二個參數,稱為 "replacer",它可以改變序列化的邏輯。如果這個函數為頂層返回上述值之一,JSON.stringify 將返回undefined。

  1. JSON.stringify({ ignored: true }, () => undefined); 
  2. // => undefined 
  3.  
  4. JSON.stringify(["ignored"], () => Symbol("hello")); 
  5. // => undefined 

需要注意的是,其中的許多東西實際上只影響到頂層的序列化。例如,JSON.stringify({foo: undefined}),返回字符串"{}",這并不令人驚訝。

我還想提一下,TypeScript的類型定義在這里是不正確的。例如,下面的代碼類型的校驗可以通過:

  1. const result: string = JSON.stringify(undefined); 

在第2部分中,我們將討論如何更新 TypeScript 的定義以確保其正確性。

JSON.stringify 也可能遇到問題,導致它拋出一個錯誤。在正常情況下,有四種情況會發生:

循環引用會導致拋出一個類型錯誤。

  1. const b = { a }; 
  2. a.b = b; 
  3.  
  4. JSON.stringify(a); 
  5. // => TypeError: cyclic object value 

注意,這些錯誤消息在不同瀏覽器可能提示是不樣的,例如,Firefox 的錯誤信息與Chrome的不同。

BigInts不能用JSON.stringify 進行序列化,這些也會導致一個TypeError。

  1. JSON.stringify(12345678987654321n); 
  2. // => TypeError: BigInt value can't be serialized in JSON 
  3.  
  4. JSON.stringify({ foo: 456n }); 
  5. // => TypeError: BigInt value can't be serialized in JSON 

帶有 toJSON 函數的對象將被運行。如果這些函數拋出錯誤,它將冒泡到調用者。

  1. const obj = { 
  2.   foo: "ignored"
  3.   toJSON() { 
  4.     throw new Error("Oh no!"); 
  5.   }, 
  6. }; 
  7.  
  8. JSON.stringify(obj); 
  9. // => Error: Oh no

你可以傳遞第二個參數,稱為 replacer。如果這個函數拋出一個錯誤,它將冒泡。

  1. JSON.stringify({}, () => { 
  2.   throw new Error("Uh oh!"); 
  3. }); 
  4. // => Error: Uh oh! 

現在我們已經看到了 JSON.stringify 不返回字符串的情況,接下來,我們來看看如何避免這些問題。

如何避免這些問題

沒有關于如何解決這些缺陷的通用方法,所以這里只介紹一些常見的情況。

處理循環引用

根據個人經驗,JSON.stringify 在傳遞循環引用時最容易出錯。如果這對你來說是一個常見的問題,我推薦 json-stringify-safe 包,它能很好地處理這種情況。

  1. const stringifySafe = require("json-stringify-safe"); 
  2.  
  3. const a = {}; 
  4. const b = { a }; 
  5. a.b = b; 
  6.  
  7. JSON.stringify(a); 
  8. // => TypeError: cyclic object value 
  9.  
  10. stringifySafe(a); 
  11. // => '{"b":{"a":"[Circular ~]"}}' 

封裝

你可能想用你自己的自定義函數來封裝 JSON.stringify。你可以決定你想要它做什么。錯誤應該冒出來嗎?如果 JSON.stringify 返回 undefined,應該怎么做?

例如,Signal Desktop有一個名為 reallyJsonStringify 的函數,它總是返回一個用于調試的字符串。就像這樣

  1. function reallyJsonStringify(value) { 
  2.   let result; 
  3.   try { 
  4.     result = JSON.stringify(value); 
  5.   } catch (_err) { 
  6.     // If there's any error, treat it like `undefined`. 
  7.     result = undefined; 
  8.   } 
  9.  
  10.   if (typeof result === "string") { 
  11.     // It's a string, so we're good. 
  12.     return result; 
  13.   } else { 
  14.     // Convert it to a string. 
  15.     return Object.prototype.toString.call(value); 
  16.   } 

關于TypeScript類型的說明

如果你已經在用 TypeScript,可能會驚訝地發現,TypeScript對 JSON.stringify的官方定義在這里并不正確。它們實際上看起來像這樣:

  1. // Note: 這里面簡化過 
  2. interface JSON { 
  3.   // ... 
  4.   stringify(value: any): string; 

不幸的是,這是一個長期存在的問題,沒有一個完美的解決方案。

你可以嘗試修補 JSON.stringify 的類型,但每個解決方案都有一定的缺點。我建議用自定義類型定義自己的包裝器并。例如,Signal Desktop的reallyJsonStringify 的模板:

  1. function reallyJsonStringify(value: unknown): string { 
  2.   // ... 

總結

  • JSON.stringify 有時會返回 undefined,而不是一個字符串
  • JSON.stringify 有時會拋出一個錯誤
  • 我們可以通過用不同的方式包裝函數來解決這個問題

希望這篇文章能讓你對 JSON.stringify 有更全面的了解。

作者:BlackLivesMatter 譯者:前端小智

來源:devinduct 原文:https://evanhahn.com/when-stringify-doesnt-return-a-string

 

責任編輯:姜華 來源: 大遷世界
相關推薦

2024-03-25 00:10:00

JSON后端開發

2021-05-06 05:30:33

JSONstringify()parse()

2023-01-17 16:25:18

前端開發JSON

2020-06-12 09:20:33

前端Blob字符串

2020-07-28 08:26:34

WebSocket瀏覽器

2011-09-15 17:10:41

2021-02-01 23:23:39

FiddlerCharlesWeb

2022-10-13 11:48:37

Web共享機制操作系統

2009-12-10 09:37:43

2019-06-11 15:25:03

JSON性能前端

2021-12-11 18:59:35

JavascriptJSON應用

2010-08-23 09:56:09

Java性能監控

2022-12-05 14:50:53

2020-09-15 08:35:57

TypeScript JavaScript類型

2022-11-04 08:19:18

gRPC框架項目

2020-03-29 20:16:09

JavaScript前端技術

2020-05-25 14:37:31

JSON.string前端秘密特性

2021-10-17 13:10:56

函數TypeScript泛型

2012-11-23 10:57:44

Shell

2020-08-11 11:20:49

Linux命令使用技巧
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产乱码精品一区二区三区中文 | 色综合99| 丁香五月网久久综合 | 国产91九色 | 亚洲日韩中文字幕一区 | 高清一区二区三区 | 精品国模一区二区三区欧美 | 久久草在线视频 | 四虎影视免费在线 | 一区二区日韩 | 一区二区国产精品 | 久久99精品久久久久久国产越南 | 久久国产精品一区二区三区 | 亚洲一区二区三区免费在线 | 伊人免费视频二 | 久久九 | 成人国产网站 | 嫩草最新网址 | 99国产精品一区二区三区 | 在线观看黄视频 | 91亚洲免费 | 美女视频h | 日本高清视频在线播放 | 精品在线一区 | 久久精品国产一区老色匹 | 97操操 | 免费在线黄色av | 国产精品一二三区 | 国产成人在线视频免费观看 | 综合久久综合久久 | 五月婷婷导航 | 久久久久亚洲精品 | 毛片免费看的 | 日本视频一区二区 | 农村黄性色生活片 | 亚洲精选一区 | 成人精品在线观看 | 久久国产日韩欧美 | 日韩精品中文字幕一区二区三区 | 我要看黄色录像一级片 | 成人美女免费网站视频 |