JSON.stringify 方法模拟

先严格判断类型:

function getType(vari) {
  return Object.prototype.toString.call(vari).slice(8, -1)
}

然后处理各种类型的数据:

function toStringify(obj) {
  let str = ''
  switch (getType(obj)) {
    case 'Object': // 对象类型需要遍历递归
      str += '{'
      Object.keys(obj).forEach(k => {
        let res = toStringify(obj[k])
        if (res) {
          str += `"${k}":${res},`
        }
      })
      return str.slice(0, -1) + '}'
    case 'Array': // 数组类型需要遍历递归
      str = '['
      obj.forEach(k => {
        let res = toStringify(k)
        if (res) {
          str += res + ','
        }
      })
      return str.slice(0, -1) + ']'
    case 'Date': // 日期类型需要toJSON转日期字符串
      return `"${obj.toJSON()}"`
    case 'String': // 字符串需要加引号
      return `"${obj}"`
    case 'Number': // 数字类型直接返回
      return `${obj}`
    case 'Boolean': // 布尔类型true和false转字符串
      if (obj === true) {
        return `true`
      }
      return `false`
    case 'RegExp': // 以下类型直接转空对象字符串
    case 'Set':
    case 'Map':
    case 'WeakMap':
    case 'WeakSet':
    case 'ArrayBuffer':
    case 'Blob':
    case 'Int32Array':
    case 'Int8Array':
    case 'Int16Array':
      return `{}`
    case 'Null': // null转字符串
      return `null`
    case 'BigInt': // bigint类型报错
      throw Error('Do not know how to serialize a BigInt')
      return
    case 'Function': // 以下三个及其它类型返回空忽略
    case 'Undefined':
    case 'Symbol':
    default:
      return
  }
}

其实很简单,只需要判断类型,该转什么就转什么,然后拼接,上面只罗列了21种类型,如果还有其它的加上就行

posted @ 2021-03-26 18:29  前端杂货  阅读(162)  评论(0编辑  收藏  举报