序
JSON是一种轻量级的数据格式,可以很容易地表示复杂的数据结构。JSON有两个方法:stringify()和parse()。在简单的情况下,这两种方法可以分别将JavaScript序列化为JSON字符串,并将JSON解析为原生JavaScript值。
本文重点介绍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对象时,所有函数和原型成员都被有意从结果中省略。此外,任何值未定义的属性都将被跳过。最终结果是所有实例属性都是有效的JSON数据类型。
JSON.stringify()方法总共可以接受三个参数,其中两个是可选的(分别是第二个和第三个参数)。这两个可选参数可用于指定序列化JavaScript对象的其他方式。第二个参数是filter,可以是数组,也可以是函数;第三个参数是缩进结果JSON字符串的选项。通过单独或组合使用这些参数,可以更好地控制JSON序列化。
2、第二个参数–过滤器
如果第二个参数是一个数组,那么JSON.stringify()返回的结果将只包含数组中列出的对象属性。例如,下面的例子:
let json1 = { title: "Json.stringify", author: [ "浪里行舟" ], year: 2021, like: 'frontend', weixin: 'frontJS'};let jsonText = JSON.stringify(json1, ['weixin']);
在这个例子中,JSON.stringify()方法的第二个参数是一个包含字符串的数组:”卫辛”。它对应于要序列化的对象中的属性,因此生成的JSON字符串将只包含该属性:
"{"weixin":"frontJS"}"
如果第二个参数是函数,则行为不同。所提供的函数接收两个参数:属性名(键)和属性值(值)。根据这个键,可以决定对相应的属性执行什么操作。这个键总是一个字符串,但是如果值不属于键/值对,它将是空字符串。
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的第二个参数是一个函数,那么它的返回值是未定义的,那么对应的属性就不会被序列化。如果返回其他值,则返回值将用于替换序列化的原始值。
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}
JSON.stringify()在处理数据时既考虑了数据转换,又考虑了易读性。但是,很容易读,这一点往往被忽略。
4、托吉森()方法–自定义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)); // ["浪里行舟"]
注意arrow函数不能用于定义toJSON()方法。主要原因是arrow函数的词法范围是全局范围,这在本例中是不合适的。
二,使用情景
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时
本地/会话存储默认只能存储字符串,但在实际开发中,我们经常需要存储对象类型。这时候我们需要在存储的时候用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)
i***ge.png
这就是用JSON.stringify把一个对象转换成JSON字符串,然后用JSON.parse把字符串解析成一个对象。随着时间的推移,一个新的对象产生了,新的对象会开辟一个新的栈来实现深度拷贝。
这种方法虽然可以实现数组或对象的深度***,但是不能处理函数和正则性,因为两者都基于JSON.stringify和JSON.parse处理后,得到的正则性就不再正则(变成空 objects),得到的函数也不再是函数(变成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值在序列化的过程中会被转换成 nullJSON.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 defined at <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的,开发的时候要避开这些坑!
本文来自暮以随然投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/572853.html