基本数据类型
string、number、boolean、undefined、null、symbol(es6)、bigint(es11)
引用数据类型
Object、Array、Date、RegExp、Function 等
JS类型检测的四种方法
typeof、instanceof、constructor、Object.prototype.tostring.call()
typeof
typeof 操作符返回一个字符串,表示未经计算的操作数的类型
console.log(typeof '123') // string
console.log(typeof 123) // number
console.log(typeof true) // boolean
console.log(typeof undefined) // undefined
console.log(typeof null) // object
console.log(typeof Symbol()) // symbol
console.log(typeof 123n) // bigint
console.log(typeof function () {}) // function
console.log(typeof {}) // object
console.log(typeof []) //object
console.log(typeof new Date()) // object
console.log(typeof /\b/) // object
console.log(typeof Infinity) // number
console.log(typeof NaN) // number
typeof 能够辨别的类型
类型 | 结果 |
---|---|
String | “string” |
Number | “number” |
Boolean | “boolean” |
Undefined | “undefined” |
BigInt | “bigint” |
Symbol | “symbol” |
Funtion对象 | “function” |
Null | “object” |
其他对象 | “object” |
typeof检测的缺点
- 对引用数据类型检测不明确,不能明确判断Object、Array、Date等类型
- 对null的判断为object
补充:typeof null 为什么是 object
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 “object”。
instanceof
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,存在返回true,不存在返回false
const num = new Number(1)
const string = new String('nice day')
const boolean = new Boolean(true)
const reg = new RegExp(/\d/)
const date = new Date()
const obj = {}
const nonObj = Object.create(null)
const fun = new Function()
const arr = new Array()
console.log(num instanceof Number) // true
console.log(string instanceof String) // true
console.log(boolean instanceof Boolean) // true
console.log(reg instanceof RegExp) // true
console.log(date instanceof Date) // true
console.log(obj instanceof Object) // true
console.log(nonObj instanceof Object) // false 一种创建非 Object 实例的对象的方法
console.log(fun instanceof Function) // true
console.log(arr instanceof Array) // true
console.log(string instanceof Object) // true
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
- 凡是在原型链上的构造函数,instanceof返回结果都是true
```javascript
const arr = [1, 2, 3]
console.log(arr instanceof Array) // true
console.log(arr instanceof Object) // true
- 不能检测null和undefined
对于特殊的数据类型 null 和 undefined,他们的所属类分别是 Null 和 Undefined,但是浏览器把这两个类保护起来了,不允许在外面访问使用。
constructor
constructor是原型对象上的方法,指向它的构造函数。可以获取实例的隐式原型对象上的constructor,检测是否为所属类
console.log(new Array().__proto__.constructor === Array) // true
console.log(new RegExp().__proto__.constructor === RegExp) // true
console.log(new Date().__proto__.constructor === Date) // true
console.log(new Object().__proto__.constructor === Object) // true
console.log(new Function().__proto__.constructor === Function) // true
constructor检测的优缺点
优点
- 可以检测各种引用数据类型
缺点
- 不能检测null和 undefined,因为它们没有constructor属性
- constructor可能因为被改写而导致结果不准确
function Foo() {}
Foo.prototype = new Array()
const foo = new Foo()
console.log(foo.__proto__.constructor === Array) // true 由于constructor被改写导致与预期结果不一致
Object.prototype.toString.call()
Object.prototype.toString.call()会返回一个字符串,[object 被检测实例的所属类]
console.log(Object.prototype.toString.call('123')) // [object String]
console.log(Object.prototype.toString.call(123)) // [object Number]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call(Symbol())) // [object Symbol]
console.log(Object.prototype.toString.call(123n)) // [object BigInt]
console.log(Object.prototype.toString.call(function () {})) // [object Function]
console.log(Object.prototype.toString.call([1, 2, 3])) // [object Array]
console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call(/\d/)) // [object RegExp]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
console.log(Object.prototype.toString.call(new Error())) // [object Error]
(function () {
console.log(Object.prototype.toString.call(arguments)) // [object Arguments]
})()
// 浏览器提供的
console.log(Object.prototype.toString.call(document)) // [object HTMLDocument]
Object.prototype.toString.call()的优缺点
优点
- 能检测各种数据类型
缺点
- 检测结果需要通过截取获得
封装一个数据类型检测的函数
function getType(value) {
const str = Object.prototype.toString.call(value)
const type = str.slice(8, -1)
return type
}