JSON.stringify()的陷阱及其隐藏的秘密

开发 前端
JSON.stringify()乍一看可能很简单,但它充满了怪癖、边缘情况和隐藏的力量。通过了解它的局限性并利用它的论点,您可以避免常见的陷阱并像专业人士一样使用它。

如果你接触过 JavaScript,很有可能遇到过 JSON.stringify()—— 这个可靠的工具可以将对象转换为 JSON 字符串。无论是通过 API 发送数据还是保存结构化数据,对于任何 Web 开发者来说,JSON.stringify() 实际上都是一个必经之路。但尽管它看起来就像挥动魔杖一样简单,表面之下却隐藏着陷阱。让我们以一种有趣的方式深入探索 JSON.stringify() 这个古怪的世界,并了解一些历史趣闻!

简史:JSON.stringify() 从何而来?

在我们探索陷阱之前,让我们回到它的最初。JSON.stringify()是在 ECMAScript 5(ES5)中引入的,该脚本于 2009 年完成。目的是什么?以机器和人类都可读的方式简化数据交换。

有趣的事实:JSON(JavaScript 对象表示法)本身最初是由 Douglas Crockford 在 2000 年代初期构思的,他正在寻找一种轻量级的数据格式来取代 XML。

JSON.stringify() 的陷阱

1、循环引用:兜兜转转我们走!

循环引用是JSON.stringify()的最终禁忌。如果你尝试字符串化引用自身的对象,你会得到一个很清晰的报错:Uncaught TypeError。

const obj = {};
obj.self = obj;

JSON.stringify(obj); // Uncaught TypeError: Converting circular structure to JSON

有趣的事实:您可以说JSON.stringify()具有“无无限循环”策略!它只是不适合递归对象。要是逃离生活的圈子就这么容易就好了,对吧?

2、不可枚举的属性和符号?不受欢迎!

当使用JSON.stringify()时,任何不可枚举或基于 Symbol 的属性都会像魔术一样消失得无影无踪。

const obj = {};
Object.defineProperty(obj, 'hidden', { value: 'secret', enumerable: false });
obj[Symbol('id')] = 123;

console.log(JSON.stringify(obj)); // {}

有趣的事实:不可枚举的属性就像 JavaScript 的忍者 — 安静、不可见,并且完全被JSON.stringify()忽略!

3、未定义的值是重影

undefined 值以及函数和 Symbol 将被完全忽略。它们不会在您的最终 JSON 输出中被剪切。

const obj = {
  name: 'John',
  age: undefined,
  greet: function() { console.log('Hello!'); },
};

console.log(JSON.stringify(obj)); // {"name":"John"}

有趣的事实:想象一下,undefined的价值观就像在聚会上被排除在客人名单之外的人。如果他们不受欢迎,他们就不会出现!

4、NaN 和 Infinity — Math Gone MIA

如果您的对象包含 NaN 或 Infinity,则它们在最终的 JSON 字符串中将替换为 null。

const obj = { value: NaN, count: Infinity };
console.log(JSON.stringify(obj)); // {"value":null,"count":null}

有趣的事实:NaN是一个悖论。它被称为 “数字”,但不是 1!难怪 JSON.stringify()把它当作幽灵。

5、日期变成字符串 — 不包括时间旅行

字符串化后,日期不会保留为 Date 对象。相反,它们将被转换为 ISO 字符串。

const obj = { date: new Date() };
console.log(JSON.stringify(obj)); // {"date":"2024-09-11T12:00:00.000Z"}

有趣的事实:JavaScript 的 Date 对象因其怪癖而臭名昭著。至少当JSON.stringify()将其转换为字符串时,它是一致的!

6、属性顺序 — 不是你所期望的

意外的JSON.stringify()不保留属性的顺序。事实上,它可能会按字母顺序对它们进行排序。

const obj = { b: 1, a: 2 };
console.log(JSON.stringify(obj)); // {"a":2,"b":1}

有趣的事实:您可能会说JSON.stringify()有点强迫症。它喜欢按字母顺序排序,无论您喜欢与否!

原型消失 — 只剩下最基本的骨架

方法和原型属性?逝。当JSON.stringify()执行其操作时,它只留下对象的直接属性。

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, ${this.name}!`);
};

const john = new Person('John');
console.log(JSON.stringify(john)); // {"name":"John"}

有趣的事实:原型就像电影中的幕后工作人员 — 必不可少,但观众从未见过(或者在这种情况下,JSON.stringify())。

JSON.stringify()参数的强大功能

虽然陷阱很多,但不要忘记JSON.stringify()通过其参数提供的强大自定义选项!

1、替代品:Filter Master

replacer参数允许您自定义字符串化的内容。它可以是筛选或转换值的函数,也可以是将某些属性列入白名单的数组。

replacer作为函数:

const user = { name: 'John', age: 30 };
const jsonString = JSON.stringify(user, (key, value) => {
  return key === 'age' ? undefined : value;
});
console.log(jsonString); // {"name":"John"}

replacer数组中:

const user = { name: 'John', age: 30, city: 'New York' };
const jsonString = JSON.stringify(user, ['name', 'city']);
console.log(jsonString); // {"name":"John","city":"New York"}

有趣的事实:replacer的争论就像俱乐部的保镖,决定谁可以进入,谁在门口被拒之门外。

2、space:JSON,但很漂亮

space参数允许您添加缩进以提高可读性。无论您喜欢2个空格还是制表符,这个参数都是您的好朋友。

const obj = { name: 'John', age: 30 };
console.log(JSON.stringify(obj, null, 2));

/*
{
  "name": "John",
  "age": 30
}
*/

console.log(JSON.stringify(obj, null, "*****")); 
/*
{
*****"name": "John",
*****"age": 30
}
*/

有趣的事实:space争论就像你的室内设计师。它使您的 JSON 输出看起来美观,因为谁不喜欢一些好的格式呢?

结论

要接受JSON.stringify()的怪异之处。

JSON.stringify()乍一看可能很简单,但它充满了怪癖、边缘情况和隐藏的力量。通过了解它的局限性并利用它的论点,您可以避免常见的陷阱并像专业人士一样使用它。

请记住,这不仅仅是将对象转换为字符串,而是了解数据的表示方式。因此,下次您使用JSON.stringify()时,您将准备好避开它隐藏的陷阱并充分利用它的灵活性!

责任编辑:武晓燕 来源: 宇宙一码平川
相关推荐

2020-03-29 20:16:09

JavaScript前端技术

2020-05-25 14:37:31

JSON.string前端秘密特性

2019-06-11 15:25:03

JSON性能前端

2021-12-11 18:59:35

JavascriptJSON应用

2021-05-06 05:30:33

JSONstringify()parse()

2022-12-05 14:50:53

2021-12-22 09:08:39

JSON.stringJavaScript字符串

2022-08-31 22:50:13

JavaScript函数JSON

2023-01-17 16:25:18

前端开发JSON

2024-03-25 00:10:00

JSON后端开发

2022-03-10 09:11:33

JavaScrip开发JSON

2011-08-09 10:41:52

Mac OS X Li

2021-10-15 10:04:37

云计算安全云服务

2023-12-04 18:31:59

C语言函数

2024-05-08 08:32:25

架构

2024-06-12 08:54:49

Go切片参数

2021-07-09 10:29:50

云计算云计算环境云应用

2023-05-12 08:11:58

JavaScriptJSON克隆

2023-05-08 09:00:46

JSON深拷贝对象

2010-01-06 16:33:04

JSON对象标记
点赞
收藏

51CTO技术栈公众号