看到一个有意思的问题:定义一个对象,他们的value包括null,undefined,function(){},Symbol(),问他们的JSON.stringify结果是多少?

var a={
    key1:'name',
    key2:null,
    key3:undefined,
    key4:function(){},
    key5:Symbol()
}
JSON.stringify(a);

开始我以为很简单,没想到这里面还有坑。。。而且坑还很深,今天我们就看看看JSON.stringify的一些规则:

当JSON.stringify的对象的value为undefined,Function,Symbol的时候,会直接忽略(JSON.stringify第二个参数可以指定)。

这个就是上面的例子,最后的结果是"{"key1":"name","key2":null}"。

这里虽然会被忽略,但是JSON.stringify有第二个参数可以额外执行返回结果,看看下面的例子就知道了:

var obj={key1:'aaa',key2:Symbol()};
JSON.stringify(obj,(key,value)=>{
    return typeof value=='symbol'?'symbol':value;
});
/*
结果:
"{"key1":"aaa","key2":"symbol"}"
*/

本来如果value为Symbol不返回,这里判断类型,然后强制返回了一个字符串symbol。(注意,JSON.stringify第二个参数如果是方法的时候一定要有返回值,否则不能完成遍历)。

当JSON.stringify的数组里面包含undefined,Function,Symbol的时候,返回null。

看个例子:

JSON.stringify(['name',function(){},null,Symbol()]);
/*
结果
"["name",null,null,null]"
*/

当JSON.stringify的对象的key为Symbol的时候,会被完全忽略(JSON.stringify第二个参数无法指定),

var obj={name:'aaa'},symbol=Symbol();
obj[symbol]='bbb';
JSON.stringify(obj,(key,value)=>{
    console.log(key,value);
    return value;
});

根据上面的例子我们可以知道,如果JSON.stringify不返回可以通过第二个参数方法指定,但是如果key为Symbol的时候,遍历的时候是无法遍历到的,因此也就无法返回了。

JSON.stringify如果遇到不可枚举类型,忽略。

var obj=Object.create(null,{
    x:{
        value:'x',
        enumerable:false    
    },
    y:{
        value:'y',
        enumerable:true
    }
});
JSON.stringify(obj);

因为不可枚举类型的key也是无法遍历到的,因此也无法操作返回。

其他注意的点:

JSON.stringify第二个参数除了指定一个方法,还可以是一个数组,这样可以指定key进行字符串化(前提是正常可以转的,如果遇到特殊另当别论)。

var obj={key1:'a',key2:'b',key3:'c'};
JSON.stringify(obj,['key1','key3']);
/*
结果:
"{"key1":"a","key3":"c"}"
*/

上面的例子中指定了key1和key3,那么key2就不会在结果里面。

JSON.stringify还有第三个参数,这个参数是用来控制返回结果的样式的,看个简单的demo:

var obj={key1:'a',key2:'b',key3:'c'};
JSON.stringify(obj,null,10);
/*
结果:
"{
    "key1": "a",
    "key2": "b",
    "key3": "c"
}"
*/
JSON.stringify(obj,null,‘aaa‘);
/*
结果:
"{
aaa"key1": "a",
aaa"key2": "b",
aaa"key3": "c"
}"
*/

如果第三个参数为数组(最多为10),那么每个每次换行都会空10格子。

如果第三个参数为字符串(最多10个,例如'aaa','\t'等),那么每个每次换行都会填充它们。

如果JSON.stringify的对象本身有toJSON方法,那么直接调用toJSON方法:

var obj={key1:'a',key2:'b',key3:'c',toJSON:function(){return 'toJSON';}};
JSON.stringify(obj);
/*
结果:
"toJSON"
*/

同理,JSON.parse有两个参数,其中第二个参数里面也是用来指定key,value的。

var obj={a:'1',b:'2'};
JSON.parse(JSON.stringify(obj),(key,value)=>{
    console.log(key,value);
    return typeof value!='object'?value*2:value ;
});
/*
结果:
{a: 2, b: 4}
*/

上面的代码将一个对象里面的数字翻了一倍。

回到顶部
我要评论

所有评论

返回
邮箱:
绑定
取消
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

邮箱:
绑定邮箱后,若有回复,会邮件通知。
提交
还可以输入500个字