1、typeof
typeof
判断数据类型(判断Array,Object,null,Date,RegExp,Error这几个类型都被typeof判断为object都返回object)
typeof(null) == 'object' // true
typeof NaN == 'number' // NaN 是Number中的一种,非Number
注 Number,String,Boolean,Function,undefined,如果想判断这几种类型,那就可以使用typeof。
2、instanceof
instanceof
判断对象的原型链是否是指向构造函数的prototype :arr instanceof Array
123 instanceof Number // false
'123' instanceof String // false
false instanceof Boolean // false
null instanceof Object // Uncaught TypeError: Right-hand side of ‘instanceof’ is not an object
本质上Null
和Object
不是一个数据类型,null值并不是以Object为原型创建出来的。所以null instanceof Object报错。
但 null 确实时JavaScript中用来表示空引用
的一个特殊值,typeof null == ‘object’
== 注 == Number,String,Boolean没有检测出他们的类型,但是可以检测出通过new构造函数的方式创建的数据。
var num = new Number(123);
var str = new String('dsfsf');
var boolean = new Boolean(false);
== 注==判断是数组时,不能用instanceof,因为
[1,2] instanceof Array // true
[1, 2] instanceof Object // true
Instanceof 代码的实现:
function _instanceof(L, R) { // L:instanceof左表达式,R:为右表达式
let Ro = R.prototype // 原型
L = L.__proto__
While(true) {
if (L === null) { // 当到达L原型链顶端还未匹配,返回false
return false
}
If (L === Ro) {
return true
}
}
}
3、constructor
对象的constructor
属性:arr.constructor === Array
constructor是prototype
对象上的属性,指向构造函数。根据实例对象寻找属性的顺序,若实例对象上没有实例属性或方法时,就去原型链上寻找,因此,实例对象也是能使用constructor属性的。
new Number(234).constructor // ƒ Number() { [native code] }
undefined.constructor // Uncaught TypeError: Cannot read property 'constructor' of undefined at <anonymous>
注 除了undefined
和null
之外,其他类型都可以通过constructor属性来判断类型。
4、Object.prototype.toString.call(arr)
Object.prototype.toString.call(arr)
可以通过toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString()
来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用。
Object.prototype.toString.call(123) // "[object Number]"
Object.prototype.toString.call([1,2]) // "[object Array]"
Object.prototype.toString.call({name: 'hh'}) // "[object Object]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(false) // "[object Boolean]"
这样可以看到使用Object.prototype.toString.call()
的方式来判断一个变量的类型是最准确的方法。
总结:
封装一个获取变量准确类型的函数
fucntion getType(obj) {
let type = typeof obj
If (type !== 'object') {
return type
}
// 如果不是object类型的数据,直接用typeof 就能判断出来
// 如果是object 类型的数据,准确判断用 Object.prototype.toString.call()来判断
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1')
// \S 非空白字符
}