var a = "iamstring."; var b = 222; var c= [1,2,3]; var d = new Date(); var e = function(){alert(111);}; var f = function(){this.name="22";};
判断数据类型的方式:
1、typeof
alert(typeof a) ------------> "string" alert(typeof b) ------------> "number" alert(typeof c) ------------> "object" alert(typeof d) ------------> "object" alert(typeof e) ------------>"function" alert(typeof f) ------------> "function"
其中typeof返回的类型都是字符串形式,需注意,例如:
alert(typeof a == "string") -------------> true
alert(typeof a == String) ---------------> false
另外typeof 可以判断function的类型;在判断除Object类型的对象时比较方便。
typeof返回类型只有undefined、string、boolean、number、object、function六种,null、array、object的返回类型是object
typeof不适合判断null和引用类型。
2、instancof
instanceof用来判断A是否是B的实例,该方法也会向原型链上查找。
这种方法也存在一定问题,认为数组[]也是Object的实例。
alert(c instanceof Array) ---------------> true alert(c instanceof Object) ---------------> true alert(d instanceof Date) alert(f instanceof Function) ------------> true alert(f instanceof function) ------------> false alert(f instanceof Object) ------------> true 注意:instanceof 后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。 分析一下[]、Array、Object三者之间的关系: [].__proto__=Array.prototype,而Array.prototype.__proto__=Object.Prototype,Object.prototype.__proto__=null
因此,instanceof只能用来检测两个对象是否在一条原型链上,并不能检测出对象的具体类型。
3、Object.prototype.toString.call(obj)
Object.prototype.toString.call(a) === "[object String]" Object.prototype.toString.call(b) === "[object Number]" Object.prototype.toString.call(c) === "[object Array]" (Object.prototype.toString.call(d) ==="[object Date]" Object.prototype.toString.call(e) ==="[object Function]" Object.prototype.toString.call(f) === "[object Function]" 大小写不能写错,比较麻烦,但胜在通用。
为什么不直接用obj.toString()呢?
从原型链的角度来讲,所有对象的原型链最终都指向Object,根据JS的变量查找规则,其他对象也是可以直接访问到Object.toString()方法的,但是实际上,大部分对象都已经实现了自身的toString()方法,这样就会导致Object的toString()被终止查找,
因此,我们使用call()方法来强制执行Object的toString()方法。
Object.toString.call(obj)与Object.prototype.toString.call(obj)的区别:
由上图可知,Object对象和他的原型链上各自有一个toString()方法,第一个返回的是函数,第二个返回的是值类型。
4、constructor
console.log(("1").constructor===String); //true console.log((1).constructor===Number); //true console.log((true).constructor===Boolean); //true console.log(([]).constructor===Array); //true console.log((function(){}).constructor===Function); //true console.log(({}).constructor===Object); //true
以上确实没有问题,但是》》》》
function F(){}; F.prototype={}; var f=new F(); console.log(f.constructor===F); //false console.log(f.constructor===Function); //false console.log(f.constructor===Object); //true console.log(F.constructor===Function); //true
当一个函数F被创建时,JS引擎会自动为其添加prototype原型对象,然后该原型对象包含两个指针:__proto__和constructor,constructor用来指向函数本身。即:F.prototype.constructor==F ----->true
但是当F被当作构造函数使用时var f=new F(); 这时F原型上的constructor就会被转移到了实例对象f上,所以f.constructor==F ----->true。。如果对F.prototype赋值{},而{}是new Object()的一个实例对象,因此new Object()会将其原型上的constructor传递给{}。
通过函数判断类型
function getDataType(obj){ if(obj===null){ return null; } else if(typeof(obj)=='object'){ if(obj instanceof Array){ return 'array'; } else{ return 'object'; } } else{ return typeof(obj); } }