面试题 - 手写JSON.stringify

面试题 - 手写JSON.stringify

一、JSON.stringify方法的基本使用

  • 作用:将对象转换成JSON字符串的格式,配合JSON.parse可实现基础版的对象深拷贝
  • 语法:JSON.stringify(value[, replacer [, space]])
let myObj1 = {
  name:'Tim',
  age:10,
  friends:[1,2,3],
  sex:'boy'
}

// 第一个参数:必须,需要序列化的对象
let objToString1 = JSON.stringify(myObj1);
console.log(objToString1);  // {"name":"Tim","age":10,"friends":[1,2,3],"sex":"boy"}

// 第二个参数:需要对对象进行处理的函数
let objToString2 = JSON.stringify(myObj1 , function (key,value){
  if (typeof value === 'string') return undefined;
  return value;
})
console.log(objToString2);  // {"age":10,"friends":[1,2,3]}

// 第三个参数:对象之间的空格数
let objToString3 = JSON.stringify(myObj1,null,'  ');
console.log(objToString3);
//{
//   "name": "Tim",
//   "age": 10,
//   "friends": [
//     1,
//     2,
//     3
//   ],
//   "sex": "boy"
// }

二、JSON.stringify对各种数据类型的处理

JSON.stringify输入类型输出
基本数据类型string字符串格式
number字符串格式的数值
boolean“true”/“false”
null“null”
undefined / symbol“undefined”
NAN / ±Infinity“null”
引用数据类型(属性类型)function“undefined”
DateDate的toJSON字符串
RegExp“{}”
数组中出现了undefined、Symbol、Function/
普通的对象1 - 如果对象有toJSON方法,则序列化toJSON方法的返回值
2 - 如果对象属性值为undefined,任意函数、Symbol,则忽略
3 - 如果以Symbol为属性键的属性都被忽略

三、手写JSON.stringify方法

function jsonStringify(data){
  let type = typeof data;

  // 处理对基本数据类型的序列化
  if (type !== 'object'){
    let result = data;

    if (Number.isNaN(data) || data === Infinity){
      return "null";
    }

    if (type === "function" || type === "undefined" || type === "symbol"){
      return undefined;
    }

    // 字符串添加双引号是为了在对象递归调用时属性值添加引号
    if (type === "string"){
      return `"${data}"`;
    }

    return data;

  }else {
    // 对引用类型的处理
    // null 虽然是基本数据类型,但是 typeof null === ‘object’
    if (data === null){
      return "null";
    }

    // 处理 Date 的序列化
    if (data.toJSON && typeof data.toJSON === 'function'){
      return jsonStringify(data.toJSON())
    }

    // 处理RegExp的序列化
    if (data instanceof RegExp){
      return "{}"
    }

    // 处理数组的每一项,每一项的类型可能不同,在数组中,undefined,function、symbol类型序列化为null,递归调用
    if (data instanceof Array){
      let result = [];
      data.forEach((item,index)=>{
        if (typeof item === 'undefined' || typeof item === 'function' || typeof item === 'symbol') {
          result[index] = "null";
        } else {
          result[index] = jsonStringify(item);
        }
      });
      result = `[${result}]`;
      return result.replace(/'/g,'"');
    }

    // 处理普通对象,对于属性值为undefined、function、symbol及属性为symbol的项直接忽略掉
    let result = [];
    Object.keys(data).forEach((item,index) => {
      if (typeof item !== 'symbol'){
        if (data[item] !== undefined && typeof data[item] !== "function" && typeof data[item] !== 'symbol' ){
          result.push(`"${item}":${jsonStringify(data[item])}`)
        }
      }
    });

    return `{${result}}`.replace(/'/g,'"');
  }
}

let obj2 = {
  name:'myName',
  age:12,
  hasMarried:false,
  null:null,
  undefined:undefined,
  hobby:undefined,
  getName(){
    return this.name
  },
  date:new Date(),
  RegExp:new RegExp("a"),
  array1:[1,2,undefined,function (){},45],
  obj3:{
    name:'hello'
  }
}

// {"name":"myName","age":12,"hasMarried":false,"null":null,"date":"2021-07-21T09:41:18.270Z","RegExp":{}
,"array1":[1,2,null,null,45],"obj3":{"name":"hello"}}

四、JSON.stringify总结

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值