将对象转换为JSON字符串,即手写JSON.stringify

2023-06-27 18:57:44 浏览数 (1)

分析:

  1. Date将转为string
  2. undefined、Symbol会直接过滤掉,但如果是数组项是undefined、Symbol、Function,那么则返回null
  3. 正则RegExp会返回空对象{}
  4. NaN、Function、null会返回null,但是呢,function会被过滤掉
  5. Infinity会转为null
  6. 如果是数组的话,返回的是数组的序列化
  7. string返回原始值
  8. number、boolean则返回string
  9. Map/Set/WeakMap/WeakSet会返回空对象{}
  10. 接受三个参数,第一个是要序列化的变量,第二个是function/array,第三个是间距

上代码:

代码语言:javascript复制
function stringify(obj, fnOrArr) {
    if (typeof obj === 'function') {
        return undefined;
    }
    if (typeof obj === 'symbol') {
        return undefined;
    }
    if (obj === undefined) {
        return undefined;
    }
    if (typeof obj === 'number' && isNaN(obj)) {
        return 'null';
    }
    if (obj === Infinity) {
        return 'null';
    }
    if (obj === null) {
        return 'null';
    }
    if (Object.prototype.toString.call(obj) === '[object Date]') {
        return `'${ obj.toJSON() }'`;
    }
    if (Object.prototype.toString.call(obj) === '[object RegExp]') {
        return '{}';
    }
    if (typeof obj !== 'object') {
        return typeof obj === 'string' ? `'${ obj }'` : obj;
    }
    if (Array.isArray(obj)) {
        const arr = obj.map((list) => {
            if (list === undefined || typeof list === 'symbol' || typeof list === 'function') {
                return 'null';
            } else {
                return `${ stringify(list) }`
            }
        });
        return `'[${ arr.join(',')}]'`;
    }
    const keys = Object.keys(obj);
    const objArr = keys.map((list) => {
        // 数组内的 undefined、Symbol、Function 转为null
        if (stringify(obj[list]) !== undefined && obj[list] !== undefined) {
            return `"${ list }": ${ stringify(obj[list]) }`;
        }
    })
    // 过滤undefined
    return `{ ${ objArr.filter(list => list !== undefined).join(',') }}`;
}

示例:

代码语言:javascript复制
const map = new Map();
map.set('name', 'Jerry');
const set = new Set();
set.add('age', 32);
const weakMap = new WeakMap();
const a = {};
weakMap.set(a, 'Female');
const weakSet = new WeakSet();
const b = {};
weakSet.add(b, 'Beijing');

const obj = {
    regexp: new RegExp(),
    today: new Date(),
    fn: function (name) {
        console.log('name:', name);
    },
    name: null,
    age: undefined,
    infinity: Infinity,
    nan: NaN,
    sex: Symbol('Male'),
    staff: [ "Jerry",123, () => {}, Symbol("Sina"), undefined, null, NaN, ],
    map: map,
    set: map,
    weakMap: weakMap,
    weakSet: weakSet,
}

使用JSON.stringify得到的是:

代码语言:javascript复制
'{"regexp":{},"today":"2023-06-27T02:51:41.607Z","name":null,"infinity":null,"nan":null,"staff":["Jerry",123,null,null,null,null,null],"map":{},"set":{},"weakMap":{},"weakSet":{}}'

使用stringify得到的是:

代码语言:javascript复制
'{ "regexp": {},"today": '2023-06-27T02:51:41.607Z',"name": null,"infinity": null,"nan": null,"staff": '['Jerry',123,null,null,null,null,null]',"map": { },"set": { },"weakMap": { },"weakSet": { }}'

这个stringify不是很完善的一个方法,和原生JSON.stringify还是有一定的差距,JSON.stringify是可以接受三个参数的,我这边暂不支持,后续再加吧。

0 人点赞