深入学习JSON.stringify()

首先看一下MDN上对JSON.stringify()的解释

JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性
语法:JSON.stringify(value[, replacer [, space]])
value :要转换的值
replacer :如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转 换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化
space : 指定缩进用的空白字符串

JSON.stringify()就是将js对象或值转换成JSON字符串,比如

console.log(JSON.stringify(22)) //"22"
console.log(JSON.stringify('str')) //"str"
console.log(JSON.stringify(true)) //"true"
console.log(JSON.stringify(undefined)) //undefined
console.log(JSON.stringify(null)) //null
console.log(JSON.stringify(Symbol('foo'))) //undefined

console.log(JSON.stringify(new Date())) //"2021-05-12T10:13:37.393Z"
console.log(JSON.stringify(/a/g)) //{}
console.log(JSON.stringify({a:2,f:function(){},c:true,[Symbol('sym')]:2})) //{"a":2,"c":true}

let obj2 = {}
Object.defineProperty(obj2,'key',{
    value:2,
    enumerable:false
})
console.log(obj2) //{key:2}
console.log(JSON.stringify(obj2)) //{}

如上所示,有些类型在转换的过程中被转换为了null 或者是 undefined 甚至是一个对象中的属性直接被忽略,对象里面的不可枚举属性转换完之后也没了
在这里插入图片描述

整理了一下表格,可以来看一下json.stringify()在转换过程中的问题,具体的可以看一下MDN,我们可以根据表格的输入输出来手写一下json.stringify()这个方法

function isStringify(data){
    let type = typeof data
    // 判断基本数据类型
    if(type !== 'object'){
        // 如果是数字的话 返回
        let result = data
        // 如果是NAN或者是infinity
        if(Number.isNaN(data)||data == Infinity){
            result = "null"
        }else if(type == 'function' || type =='undefined'||type == 'symbol' ){
        //如果是function undefined 或者是symbol
            result = 'undefined'
        }else if(type =='string'){
            result = '"'+data+'"'
        }
   		//转换为字符串
        return String(result)
    }else if(type == 'object'){
        // typeof null也是object
        if(data == null){
            return "null"
        }else if(data.toJSON && typeof data.toJSON == 'function'){
            // 如果有这个方法 会直接调用这个方法
            return isStringify(data.toJSON())
        }else if(data instanceof Array){
            // 如果是数组
            let result = []
            // 遍历数组的每一项挨个处理
            data.forEach((item,index)=>{
                // 如果是undefined function symbol
                if(typeof item == 'undefined' || typeof item == 'function' ||typeof item == 'symbol'){
                    result[index] = "null"
                }else{
                    result[index] = isStringify(item)
                }
            })
            result = "[" + result + "]" //字符串拼接 将数组转换为字符串了
            return result.replace(/'/g,'"')
        }else{
            // 处理普通的对象
            let result = []
            Object.keys(data).forEach((item,index)=>{
                if(typeof item !== 'symbol'){
                    //如果键名是symbol  自动忽略
                    if(typeof data[item] !== 'undefined' && typeof  data[item] !== 'function' && typeof  data[item] !== 'symbol'){
                        // 如果键值是undefined function symbol 自动忽略

                        // 否则的话拼接成字符串key:value的方式
                        result.push('"'+item+'"'+":"+isStringify(data[item]))
                    }
                }
            })
            // 拼接成字符串然后返回
            return "{"+result+"}".replace(/'/g,'"')
        }
    }
}

测试:

let arr = [1,'str',Symbol('foo'),true,null,undefined,function(){}]
console.log(JSON.stringify(arr) == isStringify(arr)) //true


let obj = {
    date:new Date(),
    [Symbol('symbol')]:22,
    reg:new RegExp('a'),
    fun(){
        console.log(11)
    },
    b:undefined,
    s:Symbol('sym2')
}
console.log(JSON.stringify(obj) == isStringify(obj)) //true

JSON.stringify()还可以深拷贝,但是从JSON.stringify()转换为JSON字符串时候的规范来看,深拷贝中可能会有问题,还是要根据需求来使用…

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值