JSON.stringify的三个参数

今天看到了

JSON.stringify方法可以有3个参数

JSON.stringify(value[, replacer [, space]])

注意到它接收三个参数,后面2个参数是可选的。

只传一个参数

var data = {name:"niuzai",info:{age:18,sex:"male"}};

JSON.stringify(data); //{"name":"niuzai","info":{"age":18,"sex":"male"}}

这里要注意:stringily对data里的数据类型有一些要求:

  • 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。
    • 就是不能保证hash结构的顺序是按照定义输出
JSON.stringify({x: 5, y: 6});  
// '{"x":5,"y":6}' 或者 '{"y":6,"x":5}' 都可能
  • 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
  • undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。
var obj = {"undefined":undefined,"func":function(){},"symbol":Symbol("")};
JSON.stringify(data); //"{}"

var arr = [undefined,Symbol(""),function(){}];
JSON.stringify(arr); //[null,null,null]
  • 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
JSON.stringify({[Symbol("foo")]: "foo"});   //'{}'   
  • 不可枚举的属性会被忽略
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) );
// '{"y":"y"}'

两个参数

第二个参数很有意思,可以为一个过滤函数,也可以是一个数组。

当为数组时被序列化的值的每个属性都会经过该函数的转换和处理,当为数组时则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中。

过滤函数

过滤函数还是比较有意思的,你可以控制输出,比如之前提到的会被忽略的类型,可以在这里人工的处理,强制输出(当然是别的类型)。

综合举例:

let o = {
    name:"张三",
    age:19,
    sex:"boy",
    u:undefined,
    n:null,
}

let a = JSON.stringify(o);
let b = JSON.stringify(o,["name","age"]);
let c = JSON.stringify(o,["name","age","sex"],2);
let d = JSON.stringify(o,function(key,val){
    console.log("key is %s", key);
    console.log("val is %s", typeof(val));
    console.log(key);
    console.log(val);
    if(typeof(val) == "string"){
        val = val + "1";
    }
    
    return val;
});
console.log(a);//{"name":"张三","age":19,"sex":"boy","n":null}
console.log(b);//{"name":"张三","age":19}
console.log(c);//第三个参数是space缩进,最多10个空格
//  * {
//  *   "name": "张三",
//  *   "age": 19,
//  *   "sex": "boy"
//  * }
console.log(d);//{"name":"张三1","age":19,"sex":"boy1","n":null}
// key is 
// val is object

// {name: "张三", age: 19, sex: "boy", u: undefined, n: null}
// key is name
// val is string
// name
// 张三
// key is age
// val is number
// age
// 19
// key is sex
// val is string
// sex
// boy
// key is u
// val is undefined
// u
// undefined
// key is n
// val is object
// n
// null

之前因为不知道第二个参数,为了改变序列化后的值,竟然用序列化后的字符串,用正则匹配字符串来替换达到我想要的效果,如果当初知道了弟哥哥参数,就会方便很多

toJSON 方法

如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为

var data = {
  name:"niuzai",
  info:{
    age:18,
    sex:"male"
  },
  toJSON:function(){
    return "by toJSON";
  }
};

JSON.stringify(data);
//""by toJSON"";

原文地址:https://www.cnblogs.com/fqh123/p/14398867.html