一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - 編程技術(shù) - 你不知道的 JSON.stringify?。?!

你不知道的 JSON.stringify?。。?/h1>

2021-12-22 22:20大遷世界前端小智 編程技術(shù)

JSON.stringify是我們經(jīng)常用到的的一個(gè)方法,它主要作用是將 JavaScript 值和對(duì)象轉(zhuǎn)換為字符串。

你不知道的 JSON.stringify?。。?  border=

JSON.stringify是我們經(jīng)常用到的的一個(gè)方法,它主要作用是將 JavaScript 值和對(duì)象轉(zhuǎn)換為字符串。如:

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

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

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

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

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

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

什么時(shí)候 JSON.stringify 不返回字符串?

undefined、任意的函數(shù)以及 symbol 值,在序列化過程中會(huì)被忽略(出現(xiàn)在非數(shù)組對(duì)象的屬性值中時(shí))或者被轉(zhuǎn)換成 null(出現(xiàn)在數(shù)組中時(shí))。函數(shù)、undefined 被單獨(dú)轉(zhuǎn)換時(shí),會(huì)返回 undefined。

對(duì)包含循環(huán)引用的對(duì)象(對(duì)象之間相互引用,形成無限循環(huán))執(zhí)行此方法,會(huì)拋出錯(cuò)誤

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

試圖在頂層對(duì) undefined 進(jìn)行序列化,會(huì)返回 undefined。

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

嘗試序列化函數(shù)也會(huì)返回 undefined。對(duì)于常規(guī)函數(shù)、箭頭函數(shù)、異步函數(shù)和生成器函數(shù)都是如此。

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

嘗試序列化symbol 也會(huì)返回 undefined。

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

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

  1. // => undefined

這只影響到瀏覽器,因?yàn)閐ocument.all在其他環(huán)境中是不可用的,比如Node。

帶有 toJSON 函數(shù)的對(duì)象將被運(yùn)行,而不是試圖正常地序列化它們。但是如果 toJSON 返回上面的一個(gè)值,試圖在頂層序列化它將導(dǎo)致 JSON.stringify 返回undefined。

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

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

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

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

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

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

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

JSON.stringify 也可能遇到問題,導(dǎo)致它拋出一個(gè)錯(cuò)誤。在正常情況下,有四種情況會(huì)發(fā)生:

循環(huán)引用會(huì)導(dǎo)致拋出一個(gè)類型錯(cuò)誤。

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

注意,這些錯(cuò)誤消息在不同瀏覽器可能提示是不樣的,例如,F(xiàn)irefox 的錯(cuò)誤信息與Chrome的不同。

BigInts不能用JSON.stringify 進(jìn)行序列化,這些也會(huì)導(dǎo)致一個(gè)TypeError。

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

帶有 toJSON 函數(shù)的對(duì)象將被運(yùn)行。如果這些函數(shù)拋出錯(cuò)誤,它將冒泡到調(diào)用者。

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

你可以傳遞第二個(gè)參數(shù),稱為 replacer。如果這個(gè)函數(shù)拋出一個(gè)錯(cuò)誤,它將冒泡。

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

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

如何避免這些問題

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

處理循環(huán)引用

根據(jù)個(gè)人經(jīng)驗(yàn),JSON.stringify 在傳遞循環(huán)引用時(shí)最容易出錯(cuò)。如果這對(duì)你來說是一個(gè)常見的問題,我推薦 json-stringify-safe 包,它能很好地處理這種情況。

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

封裝

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

例如,Signal Desktop有一個(gè)名為 reallyJsonStringify 的函數(shù),它總是返回一個(gè)用于調(diào)試的字符串。就像這樣

  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. if (typeof result === "string") {
  10. // It's a string, so we're good.
  11. return result;
  12. } else {
  13. // Convert it to a string.
  14. return Object.prototype.toString.call(value);
  15. }
  16. }

關(guān)于TypeScript類型的說明

如果你已經(jīng)在用 TypeScript,可能會(huì)驚訝地發(fā)現(xiàn),TypeScript對(duì) JSON.stringify的官方定義在這里并不正確。它們實(shí)際上看起來像這樣:

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

不幸的是,這是一個(gè)長(zhǎng)期存在的問題,沒有一個(gè)完美的解決方案。

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

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

總結(jié)

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

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

作者:BlackLivesMatter 譯者:前端小智

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

你不知道的 JSON.stringify!??!

原文鏈接:https://mp.weixin.qq.com/s/T7QWN0MMNB3Mqh26x8C_gw

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本sss在线高清观看 | 亚洲国产在线午夜视频无 | 秋葵丝瓜茄子草莓榴莲樱桃 | 菠萝视频在线完整版 | 惩罚狠h调教灌满 | 99re8在这里只有精品23 | 免费看打屁股视频的软件 | 4hc44四虎永久地址链接 | 法国贵妇一级伦理hd | 国产高清在线精品一区二区 | 猛男壮男受bl爽哭了高h | 久久观看视频 | 4438全国免费观看 | 欧美色成人tv在线播放 | 国产精品亚欧美一区二区三区 | 久久精品一区二区三区资源网 | 暖暖视频免费观看视频中国.韩剧 | 亚洲高清无在码在线电影 | 小货SAO边洗澡边CAO你动漫 | 欧美日韩国产亚洲一区二区三区 | 2022天堂岛日产 | 亚洲精品国产在线网站 | 狠狠的撞击发泄h | 国产激情视频 | 亚洲日本va中文字幕 | 国产成人精品一区二区阿娇陈冠希 | 久久中文字幕综合不卡一二区 | 白丝打脚枪 | 极品美女穴 | jizzjizz3d动漫 | 天若有情1992国语版完整版 | 色老板在线免费视频 | 天天躁夜夜躁很很躁 | 亚洲色图欧美偷拍 | 91好色| 亚洲va欧美va国产va天堂影 | hd性欧美俱乐部中文 | 国产欧美一区二区三区免费看 | 91制片厂制作果冻传媒破解 | np高h疯狂黄暴宫口 narutomanga玖辛奈之乳 | bt天堂在线最新版在线 |