判断一个值的类型

102 阅读1分钟

判断一个值的类型

typeof

用来判断是否为一个原始类型

判断引用类型乏力

typeof null

JavaScript 诞生以来便如此 typeof null === 'object' // true

javascript 最初实现中,值由一个表示类型的标签和事件数值表示。

对象的类型标签是 0。由于 null代表是空指针,大多数平台下为0x00,因此,null的类型标签是 0

typeof 的返回值

typeof 1 // number
typeof '1' // string
typeof false // boolean
typeof Symbol() // symbol
typeof undefined // undefined
typeof function () {} // function
typeof {} // object
typeof null // object

instanceof

检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

弊端:

  1. obj instanceof Foo返回true,不代表永远返回 true; 通过改变构造函数的prototype、 通过__proto__改变对象的原型链
  2. 无法判断基本属性的类型
new Date() instanceof Date // true
new RegExp() instanceof RegExp // true
[] instanceof Array // true
[] instanceof Object // true
function () {} instanceof Object // true

实现一个 instanceof

function myInstanceof(obj, instance) {
  if (typeof obj !== 'object') {
    return flase
  }
  if (typeof instance !== 'object' && typeof instance !== 'function') {
    throw new Error('instance is not an object')
  }
  while (obj) {
    if (obj.__proto__ === instance.prototype) {
      return true
    }
    obj = obj.__proto__
  }
  return false
}

toString

使用Object.prototype.toString.call获取到类型,再过滤掉多余字符得到该值的类型

使用特殊的对象属性Symbol.toStringTag自定义对象的 toString 方法的行为

const user = {
  [Symbol.toStringTag]: 'User'
}
console.log({}.toString.call(user)) // [object User]
  • 示例:
    Object.prototype.toString.call(true) // [object Boolean]
    Object.prototype.toString.call(132) // [object Number]
    Object.prototype.toString.call('lihao') // [object String]
    Object.prototype.toString.call(null) // [object Null]
    Object.prototype.toString.call(undefined) // [object Undefined]
    Object.prototype.toString.call(Symbol()) // [object Symbol]
    Object.prototype.toString.call({}) // [object Object]
    Object.prototype.toString.call(function () {}) // [object Function]
    Object.prototype.toString.call([1, 2, 3]) // [object Array]
    Object.prototype.toString.call(new Error()) // [object Error]
    Object.prototype.toString.call(new Date()) // [object Date]
    Object.prototype.toString.call(new RegExp()) // [object RegExp]
    Object.prototype.toString.call(Math) // [object Math]
    Object.prototype.toString.call(JSON) // [object JSON]
    Object.prototype.toString.call(document) // [object HTMLDocument]
    Object.prototype.toString.call(window) // [object Window]
    

总结

来自现代 JavaScript 教程

  • typeof 判断原始数据类型,返回 stirng
  • {}.toString 判断原始数据类型,内建对象,包含Symbol.toStringTag属性的对象,返回string
  • instanceof 判断对象,返回boolean