JSON.parse和JSON.stringify的replacer

155 阅读2分钟

JSON.parse

console.log('');
console.log('================parse最后一次遍历==================');
console.log('');


/* 
replacer最后一次的返回值将成为JSON.parse的返回值
哪怕最后返回的是一个对象字符串,JSON.parse的最终返回值也是这个对象字符串
*/
var objStr2 = "{\"a\":{\"b\":\"2\"}}"
const result2 = JSON.parse(objStr2, function (k, v) {
    if (k === '') {
        console.log('key:', k); // ""
        console.log('value:', v); // { a: { b: '2' } }
        return "{ value: '最后一次遍历' }";
    }
    return v;
});
console.log('result2:', result2); // "{value: '最后一次遍历'}"


console.log('');
console.log('================parse里向外==================');
console.log('');


/* 
从对象的每层的最里面向最外面遍历
*/
const objStr1 = '{"a1":{"b1":"b1"},"a2":{"b2":"b2"}}';
const result1 = JSON.parse(objStr1, function (k, v) {
    /* 
    b1  :  b1
    a1  :  {b1: 'b1'}
    b2  :  b2
    a2  :  {b2: 'b2'}
    ""  :  {a1:{b1:'b1'},a2:{b2:'b2'}}
    */
    console.log(k, " : ", v);
    return v;
});
console.log('result1:', result1); // {a1:{b1:'b1'},a2:{b2:'b2'}}


console.log('');
console.log('================数组==================');
console.log('');


/* 
从数组元素的最里面向最外面遍历
*/
const objStr3 = '[{"a1":{"b1":"b1"}},{"a2":{"b2":"b2"}}]';
const result3 = JSON.parse(objStr3, function (k, v) {
    /* 
    b1  :  b1
    a1  :  {b1: 'b1'}
    0  :  {a1:{b1:'b1'}}
    b2  :  b2
    a2  :  {b2: 'b2'}
    1  :  {a2:{b2:'b2'}}
    ""  :  [{a1:{b1:'b1'}},{a2:{b2:'b2'}}]
    */
    console.log(k, " : ", v);
    return v;
});
console.log('result3:', result3); // [{a1:{b1:'b1'}},{a2:{b2:'b2'}}]

JSON.stringify

console.log('');
console.log('================stringify第一次遍历==================');
console.log('');


/* 
replacer第一次返回的值,将替代传入的指定值进行序列化,JSONstringify返回其处理后的结果
*/
var obj2 = { "a": { "b": "2" } };
const result2 = JSON.stringify(obj2, function (k, v) {
    if (k === '') {
        console.log('key:', k); // ""
        console.log('value:', v); // { a: { b: '2' } }
        return { value: '第一次遍历' };
    }
    return v;
});
console.log('result2:', result2); // '{"value": "第一次遍历"}'


console.log('');
console.log('================stringify外向里==================');
console.log('');


/* 
从对象的每层的最最外面向里面遍历
*/
const obj1 = { a1: { "b1": "b1" }, a2: { "b2": "b2" } };
const result1 = JSON.stringify(obj1, function (k, v) {
    /* 
    ""  :  {a1:{b1:'b1'},a2:{b2:'b2'}}
    a1  :  {b1: 'b1'}
    b1  :  b1
    a2  :  {b2: 'b2'}
    b2  :  b2
    */
    console.log(k, " : ", v);
    return v;
});
console.log('result1:', result1); // {"a1":{"b1":"b1"},"a2":{"b2":"b2"}}


console.log('');
console.log('================数组==================');
console.log('');


/* 
从数组的每个元素的最外面向里面遍历
每个数组元素遍历完后,额外遍历一次对应索引和索引值
*/
const obj3 = [{ "a1": { "b1": "b1" } }, { "a2": { "b2": "b2" } }];
const result3 = JSON.stringify(obj3, function (k, v) {
    /* 
    ""  :  [{a1:{b1:'b1'}},{a2:{b2:'b2'}}]
    0  :  {a1:{b1:'b1'}}
    a1  :  {b1: 'b1'}
    b1  :  b1
    1  :  {a2:{b2:'b2'}}
    a2  :  {b2: 'b2'}
    b2  :  b2
    */
    console.log(k, " : ", v);
    return v;
});
console.log('result3:', result3); // '[{"a1":{"b1":"b1"}},{"a2":{"b2":"b2"}}]'

总结

replacer为函数时差别如下:

  1. 遍历顺序相反
    JSON.parse 遍历属性时从每层的里面向外遍历
    JSON.stringify 遍历属性是从每层的外面向里遍历

  2. 返回值结果不同
    JSON.parse 最后一次遍历,replacer的返回值不会做任何处理,直接成为最终返回值
    JSON.stringify 第一次遍历,replacer的返回值会替代指定值进行序列化操作,并返回结果