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

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

如果你接触过 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开发 数据处理 编程技巧

推荐文章

解决 PHP 中的 HTTP 请求超时问题
2024-11-19 09:10:35 +0800 CST
Python中何时应该使用异常处理
2024-11-19 01:16:28 +0800 CST
MySQL数据库的36条军规
2024-11-18 16:46:25 +0800 CST
Nginx 防止IP伪造,绕过IP限制
2025-01-15 09:44:42 +0800 CST
用 Rust 玩转 Google Sheets API
2024-11-19 02:36:20 +0800 CST
55个常用的JavaScript代码段
2024-11-18 22:38:45 +0800 CST
Vue3中的响应式原理是什么?
2024-11-19 09:43:12 +0800 CST
ElasticSearch简介与安装指南
2024-11-19 02:17:38 +0800 CST
Vue3中如何实现响应式数据?
2024-11-18 10:15:48 +0800 CST
开发外贸客户的推荐网站
2024-11-17 04:44:05 +0800 CST
Dropzone.js实现文件拖放上传功能
2024-11-18 18:28:02 +0800 CST
一个简单的html卡片元素代码
2024-11-18 18:14:27 +0800 CST
一文详解回调地狱
2024-11-19 05:05:31 +0800 CST
Golang中国地址生成扩展包
2024-11-19 06:01:16 +0800 CST
nginx反向代理
2024-11-18 20:44:14 +0800 CST
PHP设计模式:单例模式
2024-11-18 18:31:43 +0800 CST
内网穿透技术详解与工具对比
2025-04-01 22:12:02 +0800 CST
任务管理工具的HTML
2025-01-20 22:36:11 +0800 CST
维护网站维护费一年多少钱?
2024-11-19 08:05:52 +0800 CST
程序员茄子在线接单