基本数据类型
Undefined、Null、Boolean、Number、String、Symbol(ES6 新增)和 BigInt(ES10 新增);
typeof
typeof str 通常检测数据的基本类型, 但对引用类型数据判断的话,除function会被识别出来之外,像null、{}、数组都输出为 object。
typeof null // 'object'
typeof undefined // 'undefined'
typeof 5 // 'number'
typeof '6' // 'string'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof {} // 'object'
typeof [] // 'object'
instanceof
obj instanceof Object 用于检测构造函数的原型属性是否出现在示例对象的原型链上,可以检测某个对象是否属于某个构造函数
// 定义构建函数
let Person = function() {}
let man = new Person()
man instanceof Person // true
let person = new String('xxx')
person instanceof String // true
let str = 'string'
str instanceof String // false
//关于 instanceof 的实现原理,如下:
//顺着原型链去找,直到找到相同的原型对象,返回true,否则为false
function myInstanceof(left, right) {
// 这里先用typeof来判断基础数据类型,如果是,直接返回false
if(typeof left !== 'object' || left === null) return false;
// getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
let proto = Object.getPrototypeOf(left);
while(true) {
if(proto === null) return false;
if(proto === right.prototype) return true;//找到相同原型对象,返回true
proto = Object.getPrototypeof(proto);
}
}
constructor
constructor 属性返回对象的构造函数。
let a = 1
let b = "123"
let c = true
console.log(a.constructor === Number)//true
console.log(b.constructor === String)//true
console.log(c.constructor === Boolean)//true
// 不会顺着原型链找
let arr = []
console.log(arr.constructor === Array)
console.log(arr.constructor === Object)
//缺点是可以随意更改constructor,例如
let arr = []
Array.prototype.constructor = 'a' //更改constructor
console.log(arr.constructor === Array)//false
Object.prototype.toString.call
这个方法是最准确的检测数据类型的方法,这里的 toString 并不是转为字符串,而是返回当前实例所属的类信息的字符串。因为每个对象都有 toString 方法。
然后通过 call 将 this 指向要检测的 Object。
let a = 123
console.log(Object.prototype.toString.call(a))//[object Number]
总结
- typeof只能检测除null外的基本数据类型,对于数组、对象、正则等都返回为Object
- instanceof不能检测基本数据类型,检测引用类型时会顺着原型链往上找,只要原型链上有的,都返回true,同时,可以随意更改原型链的指向,导致检测结果不准确
- constructor可以检测基本数据类型,也能分辨出数组和对象,但是我们可以随意更改constructor的值,导致检测结果不准确
- Object.prototype.toString.call(value)可以根据返回的信息准确的检测出被测数据的类型