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

2024-11-19 08:53:06 +0800 CST views 798

如果你接触过 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 — 数学失踪

如果您的对象包含 NaNInfinity,则它们在最终的 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()有点强迫症。它喜欢按字母顺序排序,无论您喜欢与否!

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

方法和原型属性?逝。当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()时,您将准备好避开它隐藏的陷阱并充分利用它的灵活性!

复制全文 生成海报 JavaScript Web开发 数据处理 编程技巧

推荐文章

Vue3 vue-office 插件实现 Word 预览
2024-11-19 02:19:34 +0800 CST
Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
Go 语言实现 API 限流的最佳实践
2024-11-19 01:51:21 +0800 CST
介绍Vue3的Tree Shaking是什么?
2024-11-18 20:37:41 +0800 CST
前端代码规范 - Commit 提交规范
2024-11-18 10:18:08 +0800 CST
html5在客户端存储数据
2024-11-17 05:02:17 +0800 CST
使用Vue 3实现无刷新数据加载
2024-11-18 17:48:20 +0800 CST
Golang - 使用 GoFakeIt 生成 Mock 数据
2024-11-18 15:51:22 +0800 CST
15 个你应该了解的有用 CSS 属性
2024-11-18 15:24:50 +0800 CST
维护网站维护费一年多少钱?
2024-11-19 08:05:52 +0800 CST
浅谈CSRF攻击
2024-11-18 09:45:14 +0800 CST
html一个全屏背景视频
2024-11-18 00:48:20 +0800 CST
Nginx rewrite 的用法
2024-11-18 22:59:02 +0800 CST
CSS 中的 `scrollbar-width` 属性
2024-11-19 01:32:55 +0800 CST
程序员茄子在线接单