基本数据类型

string、number、boolean、undefined、null、symbol(es6)、bigint(es11)

引用数据类型

Object、Array、Date、RegExp、Function 等

JS类型检测的四种方法

typeof、instanceof、constructor、Object.prototype.tostring.call()

typeof

typeof 操作符返回一个字符串,表示未经计算的操作数的类型

  1. console.log(typeof '123') // string
  2. console.log(typeof 123) // number
  3. console.log(typeof true) // boolean
  4. console.log(typeof undefined) // undefined
  5. console.log(typeof null) // object
  6. console.log(typeof Symbol()) // symbol
  7. console.log(typeof 123n) // bigint
  8. console.log(typeof function () {}) // function
  9. console.log(typeof {}) // object
  10. console.log(typeof []) //object
  11. console.log(typeof new Date()) // object
  12. console.log(typeof /\b/) // object
  13. console.log(typeof Infinity) // number
  14. console.log(typeof NaN) // number

typeof 能够辨别的类型

类型 结果
String “string”
Number “number”
Boolean “boolean”
Undefined “undefined”
BigInt “bigint”
Symbol “symbol”
Funtion对象 “function”
Null “object”
其他对象 “object”

typeof检测的缺点

  1. 对引用数据类型检测不明确,不能明确判断Object、Array、Date等类型
  2. 对null的判断为object

补充:typeof null 为什么是 object

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 “object”。


instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,存在返回true,不存在返回false

  1. const num = new Number(1)
  2. const string = new String('nice day')
  3. const boolean = new Boolean(true)
  4. const reg = new RegExp(/\d/)
  5. const date = new Date()
  6. const obj = {}
  7. const nonObj = Object.create(null)
  8. const fun = new Function()
  9. const arr = new Array()
  10. console.log(num instanceof Number) // true
  11. console.log(string instanceof String) // true
  12. console.log(boolean instanceof Boolean) // true
  13. console.log(reg instanceof RegExp) // true
  14. console.log(date instanceof Date) // true
  15. console.log(obj instanceof Object) // true
  16. console.log(nonObj instanceof Object) // false 一种创建非 Object 实例的对象的方法
  17. console.log(fun instanceof Function) // true
  18. console.log(arr instanceof Array) // true
  19. console.log(string instanceof Object) // true
  20. console.log(date instanceof Object) // true

instanceof检测的优缺点

优点

  • 解决了typeof检测引用数据类型不准确的问题

缺点

  • 不能处理字面量创建的基本数据类型 ```javascript console.log(1 instanceof Number) // false console.log(new Number(1) instanceof Number) // true

console.log(‘123’ instanceof String) // false console.log(new String(‘123’) instanceof String) // true

  1. - 凡是在原型链上的构造函数,instanceof返回结果都是true
  2. ```javascript
  3. const arr = [1, 2, 3]
  4. console.log(arr instanceof Array) // true
  5. console.log(arr instanceof Object) // true
  • 不能检测null和undefined

对于特殊的数据类型 null 和 undefined,他们的所属类分别是 Null 和 Undefined,但是浏览器把这两个类保护起来了,不允许在外面访问使用。


constructor

constructor是原型对象上的方法,指向它的构造函数。可以获取实例的隐式原型对象上的constructor,检测是否为所属类

  1. console.log(new Array().__proto__.constructor === Array) // true
  2. console.log(new RegExp().__proto__.constructor === RegExp) // true
  3. console.log(new Date().__proto__.constructor === Date) // true
  4. console.log(new Object().__proto__.constructor === Object) // true
  5. console.log(new Function().__proto__.constructor === Function) // true

constructor检测的优缺点

优点

  • 可以检测各种引用数据类型

缺点

  • 不能检测null和 undefined,因为它们没有constructor属性
  • constructor可能因为被改写而导致结果不准确
    1. function Foo() {}
    2. Foo.prototype = new Array()
    3. const foo = new Foo()
    4. console.log(foo.__proto__.constructor === Array) // true 由于constructor被改写导致与预期结果不一致

Object.prototype.toString.call()

Object.prototype.toString.call()会返回一个字符串,[object 被检测实例的所属类]

  1. console.log(Object.prototype.toString.call('123')) // [object String]
  2. console.log(Object.prototype.toString.call(123)) // [object Number]
  3. console.log(Object.prototype.toString.call(true)) // [object Boolean]
  4. console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
  5. console.log(Object.prototype.toString.call(null)) // [object Null]
  6. console.log(Object.prototype.toString.call(Symbol())) // [object Symbol]
  7. console.log(Object.prototype.toString.call(123n)) // [object BigInt]
  8. console.log(Object.prototype.toString.call(function () {})) // [object Function]
  9. console.log(Object.prototype.toString.call([1, 2, 3])) // [object Array]
  10. console.log(Object.prototype.toString.call({})) // [object Object]
  11. console.log(Object.prototype.toString.call(/\d/)) // [object RegExp]
  12. console.log(Object.prototype.toString.call(new Date())) // [object Date]
  13. console.log(Object.prototype.toString.call(new Error())) // [object Error]
  14. (function () {
  15. console.log(Object.prototype.toString.call(arguments)) // [object Arguments]
  16. })()
  17. // 浏览器提供的
  18. console.log(Object.prototype.toString.call(document)) // [object HTMLDocument]

Object.prototype.toString.call()的优缺点

优点

  • 能检测各种数据类型

缺点

  • 检测结果需要通过截取获得

封装一个数据类型检测的函数

  1. function getType(value) {
  2. const str = Object.prototype.toString.call(value)
  3. const type = str.slice(8, -1)
  4. return type
  5. }