typeof 对于基本类型,除了 null 都可以显示正确的类型

typeof 对于对象,除了函数都会显示 object

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof b // b 没有声明,但是还会显示 undefined

typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'
function jsonStringify(data) {
  const type = typeof data
  if (type !== 'object') {
    if (Number.isNaN(data) || data === Infinity) {
      //NaN 和 Infinity 序列化返回 "null"
      return 'null'
    } else if (
      type === 'function' ||
      type === 'undefined' ||
      type === 'symbol'
    ) {
      // 由于 function 序列化返回 undefined,因此和 undefined、symbol 一起处理
      return undefined
    } else if (type === 'string') {
      return '"' + data + '"'
    }
    return data
  } else {
    // type === 'object'
    if (data === null) {
      return 'null'
    } else 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, '"')
    } else {
      // 处理普通对象
      let result = []
      Object.keys(data).forEach((item, index) => {
        if (typeof item !== 'symbol') {
          //key 如果是 symbol 对象,忽略
          if (
            data[item] !== undefined &&
            typeof data[item] !== 'function' &&
            typeof data[item] !== 'symbol'
          ) {
            //键值如果是 undefined、function、symbol 为属性值,忽略
            result.push('"' + item + '"' + ':' + jsonStringify(data[item]))
          }
        }
      })
      return ('{' + result + '}').replace(/'/g, '"')
    }
  }
}