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

文章讨论了一个自定义的`stringify`函数,该函数处理各种数据类型,如日期转换为字符串,正则表达式返回空对象,以及如何处理undefined、Symbol、Function、NaN和Infinity等。与JSON.stringify不同,此函数对某些复杂类型如Map、Set、WeakMap和WeakSet的处理并不完全,返回空对象。文章通过示例展示了两者之间的差异,并指出自定义方法目前不支持JSON.stringify的额外参数功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分析:

  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,第三个是间距
    上代码:
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(',') }}`;
}

示例:

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得到的是:

'{"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得到的是:

'{ "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是可以接受三个参数的,我这边暂不支持,后续再加吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值