基本数据类型

StringNumberBooleannullundefinedSymbol(ES6)、BigInt(ES6)

引用数据类型

ObjectArrayFunctionSet(ES6)、Map(ES6)、WeakMap(ES6)、WeakSet(ES6)

判断数据类型

  1. typeof 能判断所有值类型,函数。不可对 null、对象、数组等进行精确判断,因为都返回 object
console.log(typeof undefined) // undefined
console.log(typeof 2) // number
console.log(typeof 2n) // bigint
console.log(typeof true) // boolean
console.log(typeof 'str') // string
console.log(typeof Symbol('foo')) // symbol
console.log(typeof 2172141653n) // bigint
console.log(typeof function () {}) // function
// 不能判别
console.log(typeof []) // object
console.log(typeof {}) // object
console.log(typeof new Set()) // object
console.log(typeof new Map()) // object
console.log(typeof new WeakMap()) // object
console.log(typeof new WeakSet()) // object
  1. Object.prototype.toString().call(): 可以判断所有的数据类型
Object.prototype.toString.call(2) // [object Number]
Object.prototype.toString.call(2n) // [object BigInt]
Object.prototype.toString.call('str') // [object String]
Object.prototype.toString.call(true) // [object Boolean]
Object.prototype.toString.call(undefined) // [object Undefined]
Object.prototype.toString.call(null) // [object Null]
Object.prototype.toString.call(Math) // [object Math]
Object.prototype.toString.call({}) // [object Object]
Object.prototype.toString.call([]) // [object Array]
Object.prototype.toString.call(function () {}) // [object Function]
Object.prototype.toString.call(new Set()) // [object Set]
Object.prototype.toString.call(new Map()) // [object Map]
Object.prototype.toString.call(new WeakMap()) // [object WeakMap]
Object.prototype.toString.call(new WeakSet()) // [object WeakSet]

深拷贝

/**
 * 深拷贝
 * @param {Object} obj 要拷贝的对象
 * @param {WeakMap} map 用于存储循环引用对象的地址
 */
/* 使用weakmap是为了避免内存泄漏,map的键值为强引用,当键值为引用对象时,Map存在该对象就会存在 */
function deepClone(obj = {}, map = new WeakMap()) {
  if (obj === null || obj === undefined) return obj
  if (typeof obj !== 'object') {
    return obj
  }
  if (map.has(obj)) {
    return map.get(obj)
  }

  let result = Object.prototype.toString(obj) === '[object Array]' ? [] : {}
  // 防止循环引用
  map.set(obj, result)
  for (const key in obj) {
    // 保证 key 不是原型属性
    if (obj.hasOwnProperty(key)) {
      if (typeof obj[key] === 'object') {
        // 递归调用
        result[key] = deepClone(obj[key], map)
      } else {
        result[key] = obj[key]
      }
    }
  }

  // 返回结果
  return result
}
上次更新:
贡献者: QingYiXiaoYao