JS的数据类型分为基本类型和引用类型:
基本类型:String,Boolean,Number,Null,Undefined,Symbol(Symbol为ES6新增)
引用类型:Object(其中包含了Array,Date,Function等)数组
下面会介绍经常使用的四种判断方法:app
typeof
typeof做为一个操做符,右边跟一个表达式,并返回这个表达式的数据类型。typeof A,判断A的数据类型
对于基本类型,除了null都可返回正确的结果。
对于引用类型,除了function可正确返回,其余的返回结果均为Object类型。
所以若是对String,Boolean,NUmber,Undefined,Symbol,Function的类型判断能够用typeof
如下为示例:框架
//可返回想要的结果 typeof "a" //"string" typeof true //"boolean" typeof 1 //"number" typeof undefined //"undefined" typeof Symbol() //"symbol" typeof function a(){} //"function" //不可返回想要的结果 typeof null //object typeof [] //object typeof new Date() //object
instanceof
instanceof是用来检测构造函数的prototype属性是否出如今某个实例对象的原型链上,简而言之就是判断A是否为B的实例,A instanceof B,若是A是B的实例,则返回为true,不然返回为false
对于基本类型,没法用instanceof正确判断。判断null和undefined会直接报错
对于引用类型,也不够严谨。
instanceof判断的是是否处于原型链上,而不是是否是处于原型 链最后一位,所以它并不能判断一个对象实例具体属于哪一种类型。例如 虽然instanceof能够判断出[]是Array的实例,但它认为[]也是 Object的实例,[],Array,Object在内部造成了一条原型链
如下为示例:函数
function A(){} var a = new A(); a instanceof A;//true,由于A.prototype在a的原型链上 1 instanceof Number //false "" instanceof String //false Symbol() instanceof Symbol //false true instanceof Boolean //false null instanceof Null VM137:1 Uncaught ReferenceError: Null is not defined at <anonymous>:1:17 (anonymous) @ VM137:1 undefined instanceof Undefined VM200:1 Uncaught ReferenceError: Undefined is not defined at <anonymous>:1:22 (anonymous) @ VM200:1 [] instanceof Array //true [] instanceof Object //true new Date() instanceof Date //true new Date() instanceof Object //true
instanceof还有一个问题就是它假定只有一个全局执行环境,如 果网页中包含多个框架,那实际上就存在多个不一样全局执行环境,从而 存在两个不一样版本的构造函数,若是从一个框架向另外一个框架传入数 组,那么传入的数组与在第二个框架中原生态建立的数组分别具备各自 不一样的构造函数。
如下为示例:spa
var iframe=document.createElement("iframe") document.body.appendChild(iframe); iframeArray = window.frames[0].Array; var arr = new iframeArray(1,2);//[1,2] arr instanceof Array //false arr instanceof iframeArray //true
针对这个问题,能够用ES5提供的Array.isArray()方法,它不会区分对象是在哪一个环境下建立的prototype
constructorcode
当一个函数被定义时,JS引擎会为它添加prototype原型,而后再在prototype上添加一个constructor属性,并让其指向函数的引用,以下图所示,咱们建立一个名为A的函数:
当咱们new一个A的实例时,var a = new A();A被当成了构造函数,a是A的实例对象,此时A原型上的construct被传递到了A上,所以a.construct = A对象
A利用原型对象上的construct引用了自身,当A做为构造函数来建立新的对象,原型上的construct属性就会被新建立的对象继承,从原型链角度讲,构造函数A就是新建立对象的数据类型,这样作的意义是,让新对象在生成时,都有可追溯的数据类型。一样,JS的内置对象在生成时也是这样的
如下为示例,由于null和undefined时无效的对象,因此它们不会有constructor,因此会报错。blog
"1".constructor == String //true true.constructor == Bollean // true Symbol().constuctor == Symbol // false [1].constructor == Array //true [1].constructor == Object //false new Date().constructor == Date //true new Function().constructor == Function //true 1.constructor == Number VM505:1 Uncaught SyntaxError: Invalid or unexpected token VM587:1 Uncaught ReferenceError: Bollean is not defined at <anonymous>:1:21 (anonymous) @ VM587:1 null.constructor == NULL VM636:1 Uncaught TypeError: Cannot read property 'constructor' of null at <anonymous>:1:6 (anonymous) @ VM636:1 undefined.constructor == Undefined VM698:1 Uncaught TypeError: Cannot read property 'constructor' of undefined at <anonymous>:1:11 (anonymous) @ VM698:1
从示例中能够看出,彷佛咱们能够用construct判断String,Bollean,Array,Date,Function等,可是实际上函数的constructor是不稳定的,当被调函数的prototype被重写后,再次实例化,原有的constructor会变成Object,为了开发规范,在重写对象原型时,通常都须要从新给constructor赋值,以保证对象实例的类型不被更改。继承
function A(){} a = new A() a.constructor == A //true A.prototype = {}; b = new A(); b.constructor == A //false b.constructor == Object //true a.constructor == Object //false
Object.prototype.toString.call()
这个方法时最准确最经常使用,每个继承Object的对象都有toString方法,若是toString方法没有被重写的话,会返回[Object type],其中type为对象的类型,但当除了Object类型的对象外,其余类型直接使用toString方法时,会直接返回都是内容的字符串,因此咱们须要call或者apply方法来改变toString方法的执行上下文,使用Object.prototype上的原生toString()方法判断数据类型。
如下为示例:
Object.prototype.toString.call() //"[object Undefined]" Object.prototype.toString.call("a") //"[object String]" Object.prototype.toString.call(true) //"[object Boolean]" Object.prototype.toString.call(1) //"[object Number]" Object.prototype.toString.call(1.1) //"[object Number]" Object.prototype.toString.call(null) //"[object Null]" Object.prototype.toString.call(undefined) //"[object Undefined]" Object.prototype.toString.call([1]) //"[object Array]" Object.prototype.toString.call(new Date()) //"[object Date]" Object.prototype.toString.call(Symbol()) //"[object Symbol]" Object.prototype.toString.call(function a(){}) //"[object Function]" Object.prototype.toString.call(new Function()) //"[object Function]"