不使用 JSON.stringify 实现将对象转换为 JSON 格式的字符串

此文只考虑 :基本类型, 数组, 和 Object 类型.

一、构造函数处理数据

class ToJSONString extends String {
    toString() {
        return `"${ this.valueOf() }"`;
    }
}

class ToJSONObject extends Object {
    type() {
        return 'ToJSONObject';
    }
    toString() {
        let ret = [];
        let keys = Object.keys(this);
        for (let i = 0, len = keys.length; i < len; i++) {
            ret.push(`"${ keys[ i ]}":${ this[ keys[ i ] ] }`);
        }
        return `{${ret.join( ',' )}}`;
    }
}

class ToJSONArray extends Array {
    type() {
        return 'ToJSONArray';
    }
    toString() {
        return `[${this.join( ',' )}]`;
    }
}

二、类型判断的工具函数


function isPrimaryType(value) {
    let type = typeof value;
    return type === 'number' ||
        type === 'string' ||
        type === 'boolean';
}


function isFunction(value) {
    return typeof value === 'function';
}

//类型判断函数
function gettype(value) {
    if (isPrimaryType(value)) {
        return typeof value;
    }
    if (isFunction(value)) {
        return 'Function';
    }
    if (value.type && typeof value.type === 'function') {
        return value.type();
    }
    // [object Object]
    return Object.prototype.toString.call(value).slice(8).slice(0, -1);
}

三、数据转换 

function create(target) {
    if (isPrimaryType(target)) {
        return [gettype(target) === 'string' ? new ToJSONString(target) : target, true];
    }
    if (gettype(target) === 'Object') {
        return [new ToJSONObject(), false];
    }
    if (gettype(target) === 'Array') {
        return [new ToJSONArray(), false];
    }
    return [null, true];
}

//复杂类型数据需要用递归来处理

function trace(target) {
    let [o, isPrimary] = create(target);
    if (!isPrimary) {
        let t = gettype(o);
        switch (t) {
            case 'ToJSONObject': {
                let keys = Object.keys(target);
                for (let i = 0, len = keys.length; i < len; i++) {
                    o[keys[i]] = trace(target[keys[i]]);
                }
            }
            break;

        case 'ToJSONArray': {
            for (let i = 0, len = target.length; i < len; i++) {
                o[i] = trace(target[i]);
            }
        }
        break;
        }
    }
    return o;
}

四、测试

function toJSON(target) {
    return trace(target).toString();
}
let o = {
    name: "jim",
    arr: [1, 2, 3, "4", '5'],
    test1: 1,
    test2: true,
    test: {
        name: 'jim',
        age: 19,
        gender: true
    }
};
let res = toJSON(o)
console.log(res); 
//打印出来的结果
{"name":"jim","arr":[1,2,3,"4","5"],"test1":1,"test2":true,"test":{"name":"jim","age":19,"gender":true}}

完成啦~~~~此文思路来源GitHub上的蒋坤老师,非常感谢!!!

附完整代码:

class ToJSONString extends String {
    toString() {
        return `"${ this.valueOf() }"`;
    }
}

class ToJSONObject extends Object {
    type() {
        return 'ToJSONObject';
    }
    toString() {
        let ret = [];
        let keys = Object.keys(this);
        for (let i = 0, len = keys.length; i < len; i++) {
            ret.push(`"${ keys[ i ]}":${ this[ keys[ i ] ] }`);
        }
        return `{${ret.join( ',' )}}`;
    }
}

class ToJSONArray extends Array {
    type() {
        return 'ToJSONArray';
    }
    toString() {
        return `[${this.join( ',' )}]`;
    }
}

function isPrimaryType(value) {
    let type = typeof value;
    return type === 'number' ||
        type === 'string' ||
        type === 'boolean';
}

function isFunction(value) {
    return typeof value === 'function';
}

function gettype(value) {
    if (isPrimaryType(value)) {
        return typeof value;
    }
    if (isFunction(value)) {
        return 'Function';
    }
    if (value.type && typeof value.type === 'function') {
        return value.type();
    }
    // [object Object]
    return Object.prototype.toString.call(value).slice(8).slice(0, -1);
}

/**
 * 这里只考虑基本类型, 数组, 和 Object 类型. 
 * @param {any} target 数据
 */
function create(target) {
    if (isPrimaryType(target)) {
        return [gettype(target) === 'string' ? new ToJSONString(target) : target, true];
    }
    if (gettype(target) === 'Object') {
        return [new ToJSONObject(), false];
    }
    if (gettype(target) === 'Array') {
        return [new ToJSONArray(), false];
    }
    return [null, true];
}

function trace(target) {
    let [o, isPrimary] = create(target);
    if (!isPrimary) {
        let t = gettype(o);
        switch (t) {
            case 'ToJSONObject': {
                let keys = Object.keys(target);
                for (let i = 0, len = keys.length; i < len; i++) {
                    o[keys[i]] = trace(target[keys[i]]);
                }
            }
            break;

        case 'ToJSONArray': {
            for (let i = 0, len = target.length; i < len; i++) {
                o[i] = trace(target[i]);
            }
        }
        break;
        }
    }
    return o;
}

function toJSON(target) {
    return trace(target).toString();
}
let o = {
    name: "jim",
    arr: [1, 2, 3, "4", '5'],
    test1: 1,
    test2: true,
    test: {
        name: 'jim',
        age: 19,
        gender: true
    }
};
let res = toJSON(o)
console.log(res);

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值