JSON.stringify & JSON.parse 简析
以前用到JSON的场景也不少,但是没有仔细的研究过,这几天趁着一个需求用到了,就整理了一下相关用法。
一、 JSON.stringify()
1. 语法 JSON.stringify(value[, replacer [, space]])
2. 先说一下后面两个可选参数
space:是指定缩进用的空白字符串,用于美化输出,可以是数字或字符串。
const data = {
a: 'bang',
b: null,
c: {
x: 'xxx',
y: 'yyy',
z: 90
},
d: 9527
}
JSON.stringify(data, null, 4)
// {
// "a": "bang",
// "b": null,
// "c": {
// "x": "xxx",
// "y": "yyy",
// "z": 90
// },
// "d": 9527
// }
JSON.stringify(data, null, '-')
// {
// -"a": "bang",
// -"b": null,
// -"c": {
// --"x": "xxx",
// --"y": "yyy",
// --"z": 90
// -},
// -"d": 9527
// }
replacer:转化规则,可以是一个函数或数组。
// 1. 数组
const data = {
a: 'haha',
b: 123,
c: {
d: 8080,
e: null
}
};
JSON.stringify(data, ['b', 'd'])
// {"b":123}
JSON.stringify(data, ['a', 'c'])
// {"a":"haha","c":{}}
JSON.stringify(data, ['a', 'c', 'e'])
// {"a":"haha","c":{"e":null}}
// 2. 函数
const data = {
a: 'haha',
b: 123,
c: {
b: '123',
d: 8080,
e: null
}
};
function rep (key, value) {
if (key === 'b' && typeof value === 'number') return ++value;
return value;
}
JSON.stringify(data, rep)
// {"a":"haha","b":124,"c":{"b":"123","d":8080,"e":null}}
3. value
将要序列化成 一个 JSON 字符串的值。这里面有一些类型是不能够转化的,undefined/function/symbol
1). undefined
JSON.stringify遇到undefined时,是无法被返回的,但是null是可以的,所以我在这里的处理是把undefined 转化成null
这么做的理由是因为 undefined == null //true , 这样处理后的数据是不影响做模糊判断的。
2). function
同样是无法被返回的一种类型,我的处理是转成string类型存储,这么做产生的一个问题是 JSON.parse时需要再转成function
let data = {
name: undefined,
age: 18,
type: null,
fn: ()=>{
return 999;
}
};
let rep = (key, value) => {
if (value === undefined) {
return null;
}
if (typeof value === 'function') {
return Function.prototype.toString.call(value);
}
return value;
}
JSON.stringify(data, rep)
//{"name":null,"age":18,"type":null,"fn":"()=>{\n return 999;\n }"}
3). symbol
es6新增的一种数据类型,具体留到另一篇文章里说。这里还是说JSON的问题。
// 当value是Symbol 时,能被第二个参数指定,若不指定则无法返回
// 当key是Symbol 时,会被忽略,第二个参数无法指定
let data={name: 'aaa', symbol: Symbol()};
data[Symbol()] = 'bbb';
JSON.stringify(data,(key,value)=>{
console.log(key,value);
// name aaa
// symbol Symbol()
if (typeof value === 'symbol') return 'symbol'; //只有在这里指定才能返回结果
return value;
});
//{"name":"aaa","symbol":"symbol"}
如果value 为Symbol,可以通过第二个参数来转换;但是key为Symbol的话,遍历的时候是无法遍历到的,就无法返回,类似于不可枚举类型:
let data = Object.create(null, {
name: {
value: 'aaa',
enumerable: true
},
age: {
value: 18,
enumerable: false
}
});
let a = JSON.stringify(data, (key, value) => {
console.log(key, value);
//name aaa
return value;
})
console.log(a);
//{"name":"aaa"}
二、JSON.parse()
1. 语法: JSON.parse(text[, reviver])
2. 参数:reviver 转换器, 如果传入该参数(函数),可以用来修改解析生成的原始值,调用时机在parse函数返回之前。
let data = {
name: undefined,
age: 18,
type: null,
fn: () => {
return 999;
}
};
let rep = (key, value) => {
if (value === undefined) {
return null;
}
if (typeof value === 'function') {
return Function.prototype.toString.call(value);
}
return value;
}
let jsonS = JSON.stringify(data, rep);
//{"name":null,"age":18,"type":null,"fn":"()=>{\n return 999;\n }"}
let jsonR = JSON.parse(jsonS, (key, value)=>{
if (key) {
// return eval('('+value+')');
return new Function('return '+value)()
}
return value;
});
console.log(jsonR, jsonR.fn());
// { name: null, age: 18, type: null, fn: [Function] }
//
对于reviver 函数的处理用了eval 和 new Function 两种方式,因为eval的安全性问题,并不推荐使用,优先使用后一种方式。
三、toJSON
如果有toJSON,执行 .stringify时会先执行这个方法,再执行第二个参数
toJSON 是一个覆盖函数,要慎重使用。
let data = {
name: 'nan',
age: 18,
toJSON: function () {
console.log('to');
return this.name;
}
};
JSON.stringify(data, (key,value)=>{
console.log('rep');
return value;
});
// to
// rep
// "nan"
总结:若希望用到JSON,对象中尽量只存储基础数据类型,不要出现以上几种对于数据化不友好的类型。
*** MDN文档 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
JSON.stringify & JSON.parse 简析的更多相关文章
- JSON.stringify(),JSON.parse(),toJSON()使用方法总结
今天在看<你不知道的javascript-中>第四章‘强制类型转换’的时候,发现JSON.stringify(),JSON.parse(),toJSON()有很多细节,自己也就总结测试了一 ...
- JSON.stringify() / JSON.parse()
JSON.stringify() 这个方法可以把javascript对象转换成json字符串. JSON.parse() 这个方法可以把 json 字符串转换成 javascript对象. [下面来看 ...
- JSON.stringify(),JSON.parse(),toJSON()方法使用
JSON.stringify(),将value(Object,Array,String,Number...)序列化为JSON字符串 JSON.parse(), 将JSON数据解析为js原生值 ...
- JSON stringify and parse
来源 : http://javascript.ruanyifeng.com/stdlib/date.html //解析json也可以传入一个方法, 基本上和stringify差不多,不过是逆序的, 要 ...
- JSON.stringify(),JSON.parse(),eval(string)
JSON.stringify()用于从一个对象解析出字符串 : var obj = {"name":"week","age":" ...
- JSON.stringify,JSON.parse方法
var obj={name:'zhangsan',age:'18'};/** js对象--->JSON字符串* JSON.stringify(js对象) --转化为--> JSON字符串* ...
- 解决IE6 IE7 JSON.stringify JSON 未定义问题
在项目中引入json2.js 官方http://www.json.org/ 源码地址:https://github.com/douglascrockford/JSON-js $.ajax({ url: ...
- JSON.parse() 和 JSON.stringify()
JSON.parse()和JSON.stringify() 1.parse 用于从一个字符串中解析出json 对象.例如 var str='{"name":"cpf& ...
- JSON.parse()与JSON.stringify()高级用法
JSON.parse()与JSON.stringify是将JSON对象与字符串互相转换的方法,它们还有一些参数可以让我们在实际应用中更加方便,现在介绍一下它们的高级用法 JSON.parse() JS ...
随机推荐
- 防止ARP欺骗
前言: 曾经因为宿舍里面的同学经常熬夜打游戏,好言相劝不管用,无奈之下使用arp欺骗他们的主机,使之晚上11点之后游戏延迟,掉线,最后,一到11点同学们就都上床睡觉了. 防止arp欺骗的三种思路: 在 ...
- 【Spring Data JPA篇】JPA的底层原理(二)
一.接口继承结构 二.底层原理
- appium--多点触控
前戏 对于放大缩小的,我们使用前面的滑动是不行的,例如地图的放大缩小,这里就要用到多点触控了 MultiAction是多点触控的类,可以模拟多点触控操作,主要包含add()和perform()两个方法 ...
- 【转】spring的AOP原理,使用场景是什么?
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- 一致性算法Raft
参阅:https://www.cnblogs.com/xybaby/p/10124083.html 可视化:http://thesecretlivesofdata.com/raft/
- [LeetCode] 650. 2 Keys Keyboard 两键的键盘
Initially on a notepad only one character 'A' is present. You can perform two operations on this not ...
- [LeetCode] 565. Array Nesting 数组嵌套
A zero-indexed array A of length N contains all integers from 0 to N-1. Find and return the longest ...
- [LeetCode] 410. Split Array Largest Sum 分割数组的最大值
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- Python 腾讯云短信,发送手机验证码
1.安装包 pip install qcloudsms_py 2.准备好相关参数 腾讯云短信每个月赠送100条短信,申请一个应用,获取appid,然后创建短信签名,然后创建正文模版 3.发送短信 我们 ...
- activiti在线画流程图
springboot2.2 activiti6.0 activiti-modeler 5.22.0 注明:版本不一样会导致报错 上一篇:springboot整合activiti 效果图 代码分享:ht ...