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 ...
随机推荐
- 莫烦TensorFlow_08 tensorboard可视化进阶
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt # # add layer # def add_l ...
- LeetCode 241. Different Ways to Add Parentheses为运算表达式设计优先级 (C++)
题目: Given a string of numbers and operators, return all possible results from computing all the diff ...
- Identity入门1:Claims、ClaimsIdentity、ClaimsPrincipal详解【转】
在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OWIN的 ...
- Linux学习笔记-第6天 - 问题的根本
这些知识其实看起来很简单,之前不管是在学习C语言还是bat批处理,类似结构早已熟知. 但其实运用起来并不算好,可能真正的原因还 是在于得多练习吧.希望明年的今天自己不要再纠结与这些基础性的知识.
- 获取客户端IP地址的三个HTTP请求头的区别
一.没有使用代理服务器的情况: REMOTE_ADDR = 您的 IP HTTP_VIA = 没数值或不显示 HTTP_X_FORWARDED_FOR = 没数值或不显示 二.使用透明代理服务器的情况 ...
- Xamarin.Forms移动开发系列1:介绍和安装
摘要 Xamarin成立于2011年5月16日.Xamarin 是一套基于C#语言的跨平台移动应用开发工具,2016年2月24日被微软正式收购. 前言 很早就已经听说强大的.NET生态中有一个移动开发 ...
- 8.18 NOIP模拟测试25(B) 字符串+乌鸦喝水+所驼门王的宝藏
T1 字符串 卡特兰数 设1为向(1,1)走,0为向(1,-1)走,限制就是不能超过$y=0$这条线,题意转化为从(0,0)出发,走到(n+m,n-m)且不越过$y=0$,然后就裸的卡特兰数,$ans ...
- 【转】python中numpy模块下的np.clip()的用法
转自:https://blog.csdn.net/HHTNAN/article/details/79799612 Numpy 中clip函数的使用 一维数组 其中a是一个数组,后面两个参数分别表示最小 ...
- tecplot——Fluent重叠网格解决方案
算例来源:http://blog.sina.com.cn/s/blog_af99efb50102xoh3.html 受上篇博文的启发,在tecplot当中也能采用类似的方法处理Fluent的重叠网格计 ...
- 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)
题意 题目链接:https://www.luogu.org/problem/P4827 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...