JSON.parse()

解析JSON格式的字符串。

我们通常的使用语法是:JSON.parse(s)

1
2
3
var o = JSON.parse('{"a":1,"b":2}');
console.log(o);
//Object {a: 1, b: 2}

其实它还能接收第二个参数:JSON.parse(s, reviver)

reviver是用来转换解析值的可选函数。如果指定了reviver函数,该函数会为从s中解析的每一个原始值(不是包含这些原始值的对象或数组)调用一次。reviver接收两个参数,第一个参数是属性名——对象的属性名或转换成字符串的数组序号。第二个参数是对象属性或数组元素的原始值。reviver会作为包含原始值的对象或数组的方法来调用。在特殊情况下,如果字符串s表示的是原始值而不是更常见的对象或数组时,那么该原始值会存放在一个新创建对象的属性中,属性名是空字符串。这时,reviver会在这个新创建的对象上调用一次,第一个参数是空字符串,第二个参数则是该原始值。

reviver函数的返回值会成为属性的新值。如果reviver返回第二个参数,该属性保持不变。如果reviver返回undefined(或不返回),则会从对象或数组中删除该属性,处理完后才由JSON.parse()返回给用户。

示例:

1
2
3
4
5
6
7
8
9
10
var text = '{"a":1,"_b":2,"t":1455591901242}';
var data = JSON.parse(text, function(name, value){
//移除掉所有属性名以下划线开头的属性
if(name[0] == '_') return;
//如果属性名是t,并且值为整数,则转换为Date
if(name == 't' && /^-?\d+$/.test(value))
return new Date(value);
//否则,原样返回
return value;
});

JSON.stringify()

序列化对象、数组或原始值。序列化后生成的字符串可以被JSON.parse()解析。

我们通常这样使用:JSON.stringify(o)

1
2
var s = JSON.stringify({a:1,b:2});
console.log(s);//{"a":1,"b":2}

当JSON.stringify()遇到带有名为toJSON()的方法的对象或数组时,它会调用该对象上的toJSON()方法。例如:

1
2
3
4
5
Object.prototype.toJSON = function(){
return 'hehe';
}
var s = JSON.stringify({a:1,b:2});
console.log(s);//"hehe"

其实它也能接收第二个参数:JSON.stringify(o, filter)

该参数可以是一个可选函数,用来在字符串化前做一些替换;也可以是一个数组,包含那些需要字符串化的属性名。该参数可以在字符串化的过程中添加过滤操作。如果该参数是函数,则它是一个replacer函数,与上面介绍的toJSON()类似。如果指定replacer函数,该函数会在每一个需要字符串化的值上调用,this指向定义该值的对象或数组。replacer函数的第一个参数是该对象中的对象属性名或数组序号,第二个参数是值本身。replacer函数的返回值会替换需要字符串化的值。如果replacer函数返回undefined则会被忽略。

如果JSON.stringify()的第二个参数是一个数组,该数组会作为对象属性名。只有属性名包含在数组里的值才会被序列号,其他被忽略。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var o = {
a: 1,
b: 2,
t: /\d+/
};

//指定要序列化的字段
var text = JSON.stringify(o, ['a','b']);
console.log(text); //{"a":1,"b":2}

//指定replacer函数,使RegExp得以序列化
var text2 = JSON.stringify(o, function(key, value){
console.log(typeof value);
if(value.constructor === RegExp){

return value.toString();
}
return value;
});
console.log(text2); //{"a":1,"b":2,"t":"\\d+"}
//或使用toJSON实现同样的替换
RegExp.prototype.toJSON = function(){return this.toString();}

JSON.stringify还能接收第三个参数:JSON.stringify(o, filter, indent)

使用indent参数可以指定缩进字符串或用来缩进的空格个数。

1
2
3
4
5
6
7
var t = JSON.stringify({a:1,b:2},null,4);
console.log(t);
//string
//{
// "a": 1,
// "b": 2
//}

小技巧:使用JSON.parse和JSON.stringify实现的简单的对象深度复制。

1
2
3
function cloneObject(o){ 
return JSON.parse(JSON.stringify(o));
}