一、序列化
即js中的对象转化为字符串
1.使用obj.toJSONString()
var str=obj.toJSONString(); //将JSON对象转化为JSON字符
2.使用JSON.stringify(obj)
var str=JSON.stringify(obj); //将JSON对象转化为JSON字符
JSON.stringify(value[, replacer[, space]])
参数说明:
- value:
必需, 要转换的 JavaScript 值(通常为对象或数组)。
- replacer:
可选。用于转换结果的函数或数组。可以为一个过滤函数。
如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。
如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
- space:
可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。
1.1 第二个参数存在,且第二个参数是数组。
如果第二个参数是数组(过滤器),用来指定需要序列化的属性;并且第二个参数的值在第一个数据中存在的话,那么它就会以第二个参数的值当做key,第一个参数的值为value表示。如果第二个参数数组有多项的话,以此类推...,如果不匹配数据的话,则忽略。如下代码:
简单理解就是返回第二个参数的所有项
var json = {
"name": "kongzhi",
"age": "30",
"lists": [
{"name": "xxx1", "age": "28"},
{"name": "xxx2", "age": "29"},
{"name": "xxx3", "age": "30"}
]
};
var arrs = ['lists', 'name'];
var result = JSON.stringify(json, arrs);
// 输出结果为 '{"lists":[{"name":"xxx1"},{"name":"xxx2"},{"name":"xxx3"}],"name":"kongzhi"}'
1.2 第二个参数存在,且第二个参数是方法
如果第二个参数是一个方法的话,用来自定义序列化行为;那么该函数会有两个参数:key和value,我们可以在函数内部改变json数据的值(深遍历),如下代码:
var json = {
"name": "kongzhi",
"age": "30",
"lists": [
{"name": "xxx1", "age": "28"},
{"name": "xxx2", "age": "29"},
{"name": "xxx3", "age": "30"}
]
};
var result = JSON.stringify(json, function(key, value) {
switch(key) {
case "name":
return 'longen';
case "age":
return '31';
default:
return value;
}
});
console.log(result);
// 输出结果为 '{"name":"longen","age":"31","lists":[{"name":"longen","age":"31"},{"name":"longen","age":"31"},{"name":"longen","age":"31"}]}'
1.3 第三个参数
用来美化输出的JSON字符串;用来控制结果字符串里面的间距。
可以是一个数字,可以是一个字符串
如果是一个数字, 则在字符串化时每一级别会比上一级别缩进多这个数字值的空格(最多10个空格);如果是一个字符串,则每一级别会比上一级别多缩进用该字符串(或该字符串的前十个字符)。
JSON.stringify(data,null,10);
//每一个层级比上一个多10个空格
"{
"name": "niuzai",
"info": {
"age": 18,
"sex": "male"
}
}"
JSON.stringify(data,null,'\t');
//每一个层级比上一个多一个制表符
"{
"name": "niuzai",
"info": {
"age": 18,
"sex": "male"
}
}"
如果不加第三个参数,输出会只占一行
1.4 JSON.stringify 局限性
从下面例子可以看出:
-
undefined、function、symbol 在转换后直接被忽略了
-
正则表达式转换成对象,日期转换成字符串
-
NaN、Infinity 直接变成 null
所以千万不要用 JSON.stringify
来做深拷贝!!!得不到满意的结果的!!
二、反序列化
即js中JSON字符串转化为Object
1.使用eval('('+josnStr+')')
var obj=eval("("+data+")");
为什么要 eval这里要添加 "("+data+");//”呢?
原因在于:eval本身的问题。 由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式。
2.使用jsonStr.parseJSON()
var obj = jsonStr.parseJSON(); //由JSON字符串转换为JSON对象
3.使用parse(jsonStr)
var obj = JSON.parse(data); //由JSON字符串转换为JSON对象
(3)使用场景
1.向后台传递参数、接收后台返回值
如果后台返回的是一个String(Object序列化后返回),那么需要在js中使用eval或者parse等转化为Object再使用;
如果返回时传递了类型,比如就是Object,那么直接使用就好
2.在页面间传递数据,特别是数组时
需要使用序列化,否则IE会报错:不能执行已经释放Script的代码
3.在进行本地存储时
存储在本地window.localStorage.setItem(key,value)存储的value是json序列化的字符串;获取得到的window.localSorage.getItem(key)也是json序列化的字符串,需要经过json的反序列化进行使用(常见json序列化数组)
三、问题
1. 为什么 JSON.stringify('muzidigbig') ! == 'muzidigbig'?
为什么name1不等于name2?
const name1 = JSON.stringify('muzidigbig') // => '"muzidigbig"'
const name2 = 'muzidigbig'
console.log(name1 === name2) // '"muzidigbig"' === 'muzidigbig' => false
小心使用JSON.stringify
与字符串进行比较,它会使用=其陷入困境。
若有不足请多多指教!希望给您带来帮助!