考虑类型检测,首先我们先巩固一下JS的六种数据类型:
1)原始类型:number、string、boolean、undefined、null (五种)
2)对象:object( Function、Array、Date...)
类型检测包括:typeof instanceof
typeof (适合基本类型和函数,遇到null失效)
要想判断一个数据具体是哪一种 object 的时候,我们需要利用 instanceof 这个操作符来判断,这个我们后面会说到。
来谈谈关于 typeof 的原理吧,我们可以先想一个很有意思的问题,js 在底层是怎么存储数据的类型信息呢?或者说,一个 js 的变量,在它的底层实现中,它的类型信息是怎么实现的呢?
其实,++js 在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息++
- 000:对象
- 010:浮点数
- 100:字符串
- 110:布尔
- 1:整数
but, 对于 undefined 和 null 来说,这两个值的信息存储是有点特殊的。
null:所有机器码均为0
undefined:用 −2^30 整数来表示
所以,typeof 在判断 null 的时候就出现问题了,由于 null 的所有机器码均为0,因此直接被当做了对象来看待。
var Circle=function(){
var obj=new Object();
obj.PI=3.14159,
obj.area = function( r ) {
return this.PI * r * r;
}
return obj;
};
console.log(typeof 100);
console.log(typeof true);
console.log(typeof Circle);
console.log(typeof undefined);
console.log(typeof new Object());
console.log(typeof [1 ,3]); //对于引用类型数组等都是返回object
console.log(typeof NaN); //特殊的number
console.log(typeof null); //返回的object,是历史原因造成的,为了兼容性
number
boolean
function
undefined
object
object
number
object
instanceof判断自定义的对象,但是需要注意:不同的window或iframe间的对象类型检测不能使用instanceof,使用typeof可以跨帧使用。
其实 instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。
console.log([1,3] instanceof Array ); //true
console.log(new Object() instanceof Array ); //false
Object.prototype.toString.apply( 检测对象 )
console.log(Object.prototype.toString.apply( [] ) );
console.log(Object.prototype.toString.apply( Circle) );
console.log(Object.prototype.toString.apply( null) );
console.log(Object.prototype.toString.apply( undefined) );
[object Array]
[object Function]
[object Null]
[object Undefined]
通过{}.toString拿到的类型检测适合内置对象和基元类型。
除了上面三种,还有construtor和duck type两种。