关于js类型判断的几种方法
- typeof
- instanceof
- constructor
- Object.prototype.toString.call()
typeof
示例代码如下
console.log(typeof null);
console.log(typeof '10');
输出结果
object
string
其实很容易能够看出这种方法的弊端,null 的结果也是 object,且数组的结果也是 object,那么说明这种方法无法分辨纯粹的object
instanceof
示例代码如下
function Foo(){}
var f1=new Foo();
console.log(f1 instanceof Foo);
console.log(1 instanceof Number);
输出结果
true
false
instanceof只能判断对象是否存在目标对象的原型链上,且不能判断字面量的基本数据类型
constructor
示例代码如下
var e=1;
console.log(e.constructor.name);
输出结果
Number
这种方法是通过原型的constructor属性寻找对应构造函数的name来确定数据类型
Object.prototype.toString.call()
首先要确定一个概念,Object上原型toString方法是可以返回对象的具体类型。
而Array 、Function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(Function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....)
所以要想通过toString方法来返回对象的数据类型,有两种方法,下面演示第一种:
var e=1
delete Number.prototype.toString//删除重写后的Number中的toString
console.log(e.toString());
删除Number中的toString后,再次调用,调用的就是Object原型中的toString,就能成功返回对象的数据类型。输出结果:
[object Number]
第二种方法就是直接用Object.prototype.toString.call()
console.log(Object.prototype.toString.call(e));
返回结果与第一个方法一样,就是用call,让e直接调用Object原型链上的toString,成功返回数据类型
这里补充一个关于instanceof的原理
其实instanceof就是在查找目标对象的原型链,原生代码如下
function ins(L,R){
var LP=L.__proto__
var RP=R.prototype
while(true){
if(LP==null){
return false
}
if(LP==RP){
return true
}
LP=LP.__proto__
}
}
console.log(ins(1,Number))