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

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

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

推荐文章

Redis函数在PHP中的使用方法
2024-11-19 04:42:21 +0800 CST
php客服服务管理系统
2024-11-19 06:48:35 +0800 CST
PHP 微信红包算法
2024-11-17 22:45:34 +0800 CST
解决python “No module named pip”
2024-11-18 11:49:18 +0800 CST
Mysql允许外网访问详细流程
2024-11-17 05:03:26 +0800 CST
Vue3结合Driver.js实现新手指引功能
2024-11-19 08:46:50 +0800 CST
npm速度过慢的解决办法
2024-11-19 10:10:39 +0800 CST
Elasticsearch 条件查询
2024-11-19 06:50:24 +0800 CST
Vue3中如何使用计算属性?
2024-11-18 10:18:12 +0800 CST
Linux 常用进程命令介绍
2024-11-19 05:06:44 +0800 CST
Vue3中如何扩展VNode?
2024-11-17 19:33:18 +0800 CST
使用 Nginx 获取客户端真实 IP
2024-11-18 14:51:58 +0800 CST
Go语言中实现RSA加密与解密
2024-11-18 01:49:30 +0800 CST
网络数据抓取神器 Pipet
2024-11-19 05:43:20 +0800 CST
在JavaScript中实现队列
2024-11-19 01:38:36 +0800 CST
Roop是一款免费开源的AI换脸工具
2024-11-19 08:31:01 +0800 CST
WebSQL数据库:HTML5的非标准伴侣
2024-11-18 22:44:20 +0800 CST
Grid布局的简洁性和高效性
2024-11-18 03:48:02 +0800 CST
阿里云免sdk发送短信代码
2025-01-01 12:22:14 +0800 CST
程序员茄子在线接单