前言
JSON是一种轻量级数据格式,可以方便地表示复杂数据结构。JSON对象有两个方法:stringify()和parse()。在简单的情况下,这两个方法分别可以将JavaScript序列化为JSON字符串,以及将JSON解析为原生JavaScript值。JSON.stringify MDN官方文档

本文着重介绍JSON.stringify()的使用方法和注意事项。

一、使用方法

1、基本用法

JSON.stringify()可以把一个JavaScript对象序列化为一个JSON字符串。

let json1 = {title: "Json.stringify",author: ["浪里行舟"],year: 2021
};
let jsonText = JSON.stringify(json1);

默认情况下,JSON.stringify()会输出不包含空格或缩进的JSON字符串,因此jsonText的值是这样的:

"{"title":"Json.stringify","author":["浪里行舟"],"year":2021}"

在序列化JavaScript对象时,所有函数和原型成员都会有意地在结果中省略。此外,值为undefined的任何属性也会被跳过。最终得到的就是所有实例属性均为有效JSON数据类型的表示。

在JSON.stringify()方法一共能接受3个参数,其中两个可选的参数(分别是第二、第三个参数)。这两个可选参数可以用于指定其他序列化JavaScript对象的方式。第二个参数是过滤器,可以是数组或函数;第三个参数是用于缩进结果JSON字符串的选项。单独或组合使用这些参数可以更好地控制JSON序列化。

第二个参数–过滤器

如果第二个参数是一个数组,那么JSON.stringify()返回的结果只会包含该数组中列出的对象属性。比如下面的例子:

let json1 = {title: "Json.stringify",author: ["浪里行舟"],year: 2021,like: 'frontend',weixin: 'frontJS'
};
let jsonText = JSON.stringify(json1, ['weixin']);

在这个例子中,JSON.stringify()方法的第二个参数是一个包含一个字符串的数组:“weixin”。它对应着要序列化的对象中的属性,因此结果JSON字符串中只会包含这个属性:

"{"weixin":"frontJS"}"

如果第二个参数是一个函数,则行为又有不同。提供的函数接收两个参数:属性名(key)和属性值(value)。可以根据这个key决定要对相应属性执行什么操作。这个key始终是字符串,只是在值不属于某个键/值对时会是空字符串。

const students = [{name: 'james',score: 100,}, {name: 'jordon',score: 60,}, {name: 'kobe',score: 90,}
];function replacer (key, value) {if (key === 'score') {if (value === 100) {return 'S';} else if (value >= 90) {return 'A';} else if (value >= 70) {return 'B';} else if (value >= 50) {return 'C';} else {return 'E';}}return value;
}
console.log(JSON.stringify(students, replacer, 4))

上面的代码,我们通过replacer将成绩从百分制替换为成绩等级。
值得注意的是,如果stringify的第二个参数为函数那么它的返回值如果是undefined****,那么对应的属性不会被序列化,如果返回其他的值,那么用返回的值替代原来的值进行序列化。

3、第三个参数–字符串缩进

JSON.stringify()方法的第三个参数控制缩进和空格。在这个参数是数值时,表示每一级缩进的空格数。例如,每级缩进4个空格,可以这样:

let json1 = {title: "Json.stringify",author: ["浪里行舟"],year: 2021
};
let jsonText = JSON.stringify(json1, null, 4);

这样得到的jsonText格式如下:

{"title": "Json.stringify","author": ["浪里行舟"],"year": 2021
}

4、toJSON()方法–自定义JSON序列化

有时候,对象需要在**JSON.stringify()**之上自定义JSON序列化。此时,可以在要序列化的对象中添加toJSON()方法,序列化时会基于这个方法返回适当的JSON表示。

下面的对象为自定义序列化而添加了一个toJSON()方法:

let json1 = {title: "Json.stringify",author: ["浪里行舟"],year: 2021,like: 'frontend',weixin: 'frontJS',toJSON: function () {return this.author}
};
console.log(JSON.stringify(json1)); // ["浪里行舟"]

注意,箭头函数不能用来定义toJSON()方法。主要原因是箭头函数的词法作用域是全局作用域,在这种情况下不合适。

二、使用场景

1、判断数组是否包含某对象,或者判断对象是否相等。

//判断数组是否包含某对象
let data = [{name:'浪里行舟'},{name:'前端工匠'},{name:'前端开发'},],val = {name:'浪里行舟'};
console.log(JSON.stringify(data).indexOf(JSON.stringify(val)) !== -1);//true

我们还可以使用JSON.stringify()方法,来判断两个对象是否相等。

// 判断对象是否相等
let obj1 = {a: 1,b: 2}let obj2 = {a: 1,b: 2,}
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)) // true

不过这种方式存在着较大的局限性,对象如果调整了键的顺序,就会判断出错!

// 调整对象键的位置后
let obj1 = {a: 1,b: 2}let obj2 = {b: 2,a: 1,}
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)) // false

2、使用localStorage/sessionStorage时

localStorage/sessionStorage默认只能存储字符串,而实际开发中,我们往往需要存储对象类型,那么此时我们需要在存储时利用json.stringify()将对象转为字符串,在取本地缓存时,使用json.parse()转回对象即可。

// 存数据
function setLocalStorage(key,val) {window.localStorage.setItem(key, JSON.stringify(val));
};
// 取数据
function getLocalStorage(key) {let val = JSON.parse(window.localStorage.getItem(key));return val;
};
// 测试
setLocalStorage('Test',['前端工匠','浪里行舟']);
console.log(getLocalStorage('Test'));

3、实现对象深拷贝

开发中,有时候怕影响原数据,我们常深拷贝出一份数据做任意操作,使用JSON.stringify()与JSON.parse()来实现深拷贝是很不错的选择。

let arr1 = [1, 3, {username: ' kobe'
}];
let arr2 = JSON.parse(JSON.stringify(arr1));
arr2[2].username = 'duncan';
console.log(arr1, arr2)


这是利用JSON.stringify将对象转成JSON字符串,再用JSON.parse把字符串解析成对象,一去一来,新的对象产生了,新对象会开辟新的栈,实现深拷贝。

这种方法虽然可以实现数组或对象深拷贝,但不能处理函数和正则,因为这两者基于JSON.stringify和JSON.parse处理后,得到的正则就不再是正则(变为空对象),得到的函数就不再是函数(变为null)了。

let arr1 = [1, 3, function () { }, {username: ' kobe'
}];
let arr2 = JSON.parse(JSON.stringify(arr1));
arr2[3].username = 'duncan';
console.log(arr1, arr2)

三、使用注意事项

JSON.stringify()虽然功能很强大,但是有些属性无法被stringify,所以在开发中需注意以下几种情况,以免产生一些始料未及的BUG。

1、被转换值中有 NaN 和 Infinity

let myObj = {name: "浪里行舟",age: Infinity,money: NaN,
};
console.log(JSON.stringify(myObj));
// {"name":"浪里行舟","age":null,"money":null}JSON.stringify([NaN, Infinity])
// [null,null]

2、被转换值中有 undefined、任意的函数以及 symbol 值

分为两种情况:

  • 数组,undefined、任意的函数以及symbol值在序列化的过程中会被转换成 null
JSON.stringify([undefined, function () { }, Symbol("")]);
// '[null,null,null]'
  • 非数组,undefined、任意的函数以及symbol值在序列化的过程中会被忽略
JSON.stringify({ x: undefined, y: function () { }, z: Symbol("") });
// '{}'

3、循环引用

如果一个对象的属性值通过某种间接的方式指回该对象本身,那么就是一个循环引用。比如:

let bar = {a: {c: foo}
};
let foo = {b: bar
};JSON.stringify(foo)

这种情况下,序列化会报错的:

// 错误信息
Uncaught ReferenceError: foo is not definedat <anonymous>:3:8

4、含有不可枚举的属性值时

不可枚举的属性默认会被忽略:

let personObj = Object.create(null, {name: { value: "浪里行舟", enumerable: false },year: { value: "2021", enumerable: true },
})console.log(JSON.stringify(personObj)) // {"year":"2021"}

四、总结

JSON.stringify()用于将JavaScript对象序列化为JSON字符串,这方法有一些选项可以用来改变默认的行为,以实现过滤或修改流程。不过也应该注意有些属性是无法被 stringify,所以开发时候应该避开这些坑!

参考资料

  • JavaScript高级程序设计(第4版)
  • 慎用JSON.stringify
  • 你会用JS格式化JSON吗?
  • json.stringify()的妙用
  • 你所不知道的JSON.stringify

你会用 JSON.stringify()? JSON.stringify一些坑相关推荐

  1. javascript 数组和对象的浅复制和深度复制 assign/slice/concat/JSON.parse(JSON.stringify())...

    javascript 数组和对象的浅度复制和深度复制 在平常我们用 '='来用一个变量引用一个数组或对象,这里是'引用'而不是复制下面我们看一个例子引用和复制是什么概念 var arr=[1,2,3, ...

  2. 使用JSON.parse(),JSON.stringify()实现对对象的深拷贝

    使用JSON.parse(),JSON.stringify()实现对对象的深拷贝 根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象 ...

  3. php json.parse,JSON.parse()与JSON.stringify()和eval()使用方法详解

    这次给大家带来JSON.parse()与JSON.stringify()和eval()使用方法详解,JSON.parse()与JSON.stringify()和eval()使用的注意事项有哪些,下面就 ...

  4. 【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较...

    样本:1MB的JSON文件,引入后生成500份的一个数组: 结果如下: 拷贝性能: JSON.parse(JSON.stringify()) 的方法:2523.55517578125ms immuta ...

  5. JSON(5)---JSON.stringify()

    JSON.stringify() JSON 通常用于与服务端交换数据. 在向服务器发送数据时一般是字符串. 我们可以使用 JSON.stringify() 方法将 JavaScript 对象转换为字符 ...

  6. js字符串转换为json对象JSON.parse()及将json对象转为json字符串JSON.stringify()

    一.JSON对象中有两个非常好用的方法: 1 JSON.stringify接收一个JS对象转化为json字符串 2 JSON.parse接受json字符串转化为JS对象 const my={ name ...

  7. 关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法

    JSON.parse(jsonString): 在一个字符串中解析出JSON对象 JSON.stringify(obj) : 将一个JSON对象转换成字符串 jQuery.parseJSON(json ...

  8. $.each 循环json以及JSON.parse() JSON.stringify() jQuery.parseJSON()的用法:

    $.each 循环 json 当循环的是 json 对象: var jsonStu = [{"name": "张三","score": &q ...

  9. JSON.stringify() / JSON.parse() / JSON 真是个好东西

    目录 1. JSON 基本概念 1.1 JavaScript 对象表示法 1.2 JSON 文件 1.3 JSON 语法 2. XML VS JSON 2.1 共同点 2.2 不同点 2.3 使用步骤 ...

  10. javascript json和json字符串互转

    javascript json和json字符串互转 <!DOCTYPE html> <html lang="en"><head><meta ...

最新文章

  1. C语言 一维数组 练习
  2. 哈希链表的原理及算法实现
  3. Saber2016安装包和安装详细安装步骤
  4. Books Queries(codeforces 1066)
  5. 6面向对象的程序设计
  6. 7-20 打印九九口诀表 (15 分)
  7. 先出报表还是先计提所得税_合并报表投资时点的评估增值和内部交易到底该如何理解????...
  8. 计算机视觉常用图像软件对比和分析
  9. GAMP学习-函数流程图调用(部分)(一)
  10. 个人网站的制作HTML,制作个人网站从HTML开始.doc
  11. lineedit加入边框 qt_qt qlineedit 边框
  12. 《刻意练习——如何从新手到大师》——创造天才
  13. 高通820(msm8996)camera hal源码分析
  14. Linux系统学习方法
  15. NXP-MPC5748G车载MCU使用(食用)方法(踩坑)实用指南(骗人教程)(二):使用FREERTOS点亮LED
  16. 北京时间和格林威治时间互相转化 JavaScript
  17. 热搜!中科大一博士生打印学位论文,分量堪比书籍!可“惨”的是...
  18. Cesium 基础知识和文档记录
  19. spring实现dubbo服务
  20. HR干货,怎样做好企业员工的晋升

热门文章

  1. Directx使用基础
  2. de4dot 反编译
  3. GPS之Ublox方案设计
  4. Delphi各个版本的官方下载地址,还在等机会
  5. CentOS安装锐捷认证客户端
  6. Spring Boot拦截器配置拦截登陆
  7. java格斗代码_java学习2打架代码编写
  8. html模板原型,政务管理系统原型模板分享
  9. 另存为fdf或xps加载项_2007 Microsoft Office加载项:Microsoft另存为PDF或XPS
  10. echarts导出为pdf