手写实现JSON.stringfy()

手写实现JSON.stringfy()


面试考到了这个,之前从来没看过,写的焦头烂额。

查阅 MDN 发现 JSON.stringfy() 有很多注意的点,不是单纯把所有的东西都变成了字符串


**看一下MDN的描述**

在这里插入图片描述

有些乱,总结一下

规则输入输出
1number字符串类型的数值
2NaN 和 Infinity“null”
3functionundefined
4undefinedundefined
5symbolundefined
6stringstring(注意两边的双引号)
7null“null”
8boolean“true/false”
9DateDate的toJSON字符串值
10Array数组中出现了undefined、function 和 symbol“null”
11普通object1、如果有 toJSON() 方法,那么序列化 toJSON() 的返回值;
2、如果属性值中出现了 undefined、函数、symbol,全部忽略;
3、所有以 symbol 为属性键的属性都会被完全忽略掉
12RegExp“{}”
13循环引用抛出错误
function myStringify(obj) {
  let result = '';
  var type = typeof obj;
  if (type !== 'object' || obj === null) {
    // 首先处理基本数据类型和function

    if (type == 'number' && (Number.isNaN(obj) || !Number.isFinite(obj))) {
      // 规则2:处理NaN和Infinite
      result = 'null';
    } else if (type == 'function' || type == 'undefined' || type == 'symbol') {
      // 规则345:函数、undefined、symbol 被单独转换时,会返回 undefined,
      result = 'undefined';
    } else if (type == 'string') {
      // 规则6:字符串,记得添加双引号,不能直接result = obj
      result = `"${obj}"`;
    } else {
      // 规则78:处理null 和 boolean
      result = obj;
    }
    // 转换为字符串
    result = String(result);
  } else {
    if (obj.toJSON && typeof obj.toJSON == 'function') {
      // 规则9:Date 有 toJSON() 方法,进行序列化。
      result += myStringify(obj.toJSON());
    } else if (obj instanceof Array) {
      result = [];
      obj.forEach((item, index) => {
        let itemType = typeof item;
        // 规则10:undefined、任意的函数以及 symbol 值,出现在数组中时,被转换成 null
        if (
          itemType == 'undefined' ||
          itemType == 'function' ||
          itemType == 'symbol'
        ) {
          result[index] = 'null';
        } else {
          result[index] = myStringify(item);
        }
      });
      result = `[${result}]`;
    } else {
      result = [];
      Object.keys(obj).forEach((item, index) => {
        // 规则11:所有以 symbol 为属性键的属性都会被完全忽略掉
        // Object.keys返回包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
        let valueType = typeof obj[item];
        if (
          valueType == 'undefined' ||
          valueType == 'function' ||
          valueType == 'symbol'
        ) {
          // 规则11:普通object的undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略
        } else if (obj[item] == obj) {
          // 规则13:对包含循环引用的对象执行此方法,会抛出错误。
          throw TypeError('cyclic object value');
        } else {
          result.push(`"${item}":${myStringify(obj[item])}`);
        }
      });
      // 规则12:这里其实处理了RegExp
      // Obje.keys(RegExp类型)得出一个空数组,不会进入forEach循环,直接运行下行代码,变成一个空数组
      result = `{${result}}`;
    }
  }
  return result;
}

let obj = {
  a: 1,
  b: NaN,
  c: Infinity,
  d: undefined,
  e: Symbol('123'),
  f: 'hello',
  g: null,
  h: true,
  i: new Date(),
  j: [8, 'world', { aa: 9 }],
  k: new RegExp(/dfs/),
  l: function (a, b) {
    return a + b;
  },
};

let str = myStringify(obj);
let str1 = JSON.stringify(obj);
console.log(str);
console.log(str1);

在这里插入图片描述
用JSON.parse也可以解析回去~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值