js判断数据类型很有多种方法,下面主要说下 typeof,instanceof,constructor,Object.prototype.toString.call()区别!
这个最熟悉不过了,判断数据类型很常用的方法!但是它都能判断什么数据类型呢?
console.log(typeof 2);//number console.log(typeof "2");//string console.log(typeof true);//boolean console.log(typeof undefined);//underfined console.log(typeof null);//object console.log(typeof function(){});//Function console.log(typeof [1,2,3]);//object console.log(typeof {p:1});//object很明显的看出,基本类型除非了null判断类型是object外,其他的都能很准确的作出判断,然后引用类型除非了functrion 能够准备判断出类型,其他判断都是object类型! 结论:基本类型可以作出准确判断(null除外),也不能很准确的判断出引用类型!
这个应该见过,但是用的可能不是很多,a instranceof b,意思判断 b的原型对象是否在a的原型链上! 我们来模拟下它的原理!
function instanceOfTest(a, b) { var bp = b.prototype; var ap = a.__proto__;//在原型链上找原型对象 while (true) { if (ap === bp) {// 相等就说明在原型链上找到b的原型了 return true; } else if (ap === null) {//找到尽头了,确实没有 return false; } ap = ap.__proto__; //没找到,一直往上找 }; }; console.log(instanceOfTest([], Object)); //true console.log([] instanceof Object);//true注释写的很清楚,也很直观的代码!那么它能做什么呢?它可以判断引用类型,基本类型判断不了(下面会讲原因),先看看怎么判断引用类型的
console.log([] instanceof Array);//true console.log({} instanceof Object);//true console.log(function(){} instanceof Function);//true看上去好像没啥问题,但是如果后面是Object的话,那么都返回true,因为Object是它们的祖师爷了!
console.log([] instanceof Object);//true console.log({} instanceof Object);//true console.log(function(){} instanceof Object);//true再来看看基本类型的
var a =1; console.log(a instanceof Number);//false console.log(a.constructor === Number);//true这里有个坑!其实 a是Number的实例,Number的原型也在a的原型链上!为什么 a instanceof Number结果是false? 其实是 object instranceof constructor ,注意看!是object,如果不是object全部返false,那么问题来了?为什么实例出来的对象变成了基本类型?很懵!!! 其实当我们字面量创建变量时候,后台就会创建一个对应的基本包装类型的对象,下面是它的创建过程! 1.创建String的实例 2.在实例上调用指定的方法 3.销毁这个实例
var a = "1234" //等价于 var a = new Number("1234"); var copyA = a.substr(0); a = null;这个过程是非常短暂的,这个也是引用类型和包装类型的最大区别,也就是对象的生命周期,在运行的一瞬间就被销毁了,这个也是为什么在运行的时候在包装对象上添加不了属性和方法
var a = "1234" a.add = "add"; console.log(a);//underfined知道了这个原理,那么上面疑惑也应该解决了!
顾名思义构造函数,肯定是指向构造函数,在原型上才有这个属性,由于实例出来的对象会继承原型上的属性,所以也有这个属性
console.log((1).constructor ===Number);//true console.log(true.constructor === Boolean);//true console.log("1".constructor === String);//true console.log([].constructor === Array);//true console.log(function(){}.constructor === Function);//true console.log({}.constructor === Object);//true这里有一点需要注意,当直接给原型赋值后,那么constructor指向就会改变!
function A(){ }; var p =new A(); console.log(p.constructor===A);//true A.prototype = []; var p1 =new A(); console.log(p1.constructor===A);//false console.log(p1.constructor===Array);//true这个是推荐使用的,能够比较精准的判断各种类型,原理是借用Object原型上的toString()方法!
var test = Object.prototype.toString; console.log(test.call(1));//[object Number] console.log(test.call("1"));//[object String] console.log(test.call(true));//[object Boolean] console.log(test.call(function(){}));//[object Function] console.log(test.call(undefined));//[object Undefined] console.log(test.call(null));//[object Null] console.log(test.call([]));//[object Array]