鉴于 ECMAScript 是松散类型的,因此需要有一种手段来检测给定变量的数据类型。对于这个问题,JavaScript 也提供了多种方法,但遗憾的是,不同的方法得到的结果参差不齐。
下面介绍常用的几种方法,并对各个方法存在的问题进行简单的分析
1.typeof返回的是类型名包括以下 7 种:number、boolean、symbol、string、object、undefined、function 等,(array,null除外)
1 typeof ''; // string 有效 2 typeof 1; // number 有效 3 typeof Symbol(); // symbol 有效 4 typeof true; //boolean 有效 5 typeof undefined; //undefined 有效 6 typeof null; //object 无效 7 typeof [] ; //object 无效 8 typeof new Function(); // function 有效 9 typeof new Date(); //object 无效 10 typeof new RegExp(); //object 无效
2.instanceof返回值真则返回true,否则返回 false
1 [] instanceof Array; //true 2 {} instanceof Object;//true 3 new Date() instanceof Date;//true 4 [] instanceof Object; //true
我们发现,虽然 instanceof 能够判断出 [ ] 是Array的实例,但它认为 [ ] 也是Object的实例
3.constructor 默认返回的是类型(三者中最好的)
1 ''.constructor == String //true 2 new Number(1).constructor == Number //true 3 new Function().constructor == Function //true 4 true.constructor == Boolean //true 5 new Date().constructor == Date //true 6 7 new Error().constructor == Error //true 8 [].constructor == Array //true 9 document.constructor == HTMLDocument //true 10 window.constructor == window //false
console.log('abc'.constructor)
ƒ String() { [native code] }
console.log([].constructor)
ƒ Array() { [native code] }
//可以通过截取字符串拿到类型关键字进行判断
利用字符串截取获取构造函数名称
<script type="text/javascript"> function Fn(){} var obj = new Fn(); document.write( obj.constructor === Fn ); // true 对象的constructor属性描述的就是其构造函数 var str = ''+obj.constructor; var str1 = str.replace('function','|'); var startIndex = str1.indexOf('|'); var endIndex = str1.indexOf('('); if( startIndex != -1 && endIndex != -1 ){ var name = str1.slice( startIndex+2,endIndex ); alert(name); //Fn } </script>
扫描二维码关注公众号,回复:
6249113 查看本文章
4.toString
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
1 Object.prototype.toString.call('') ; // [object String] 2 Object.prototype.toString.call(1) ; // [object Number] 3 Object.prototype.toString.call(true) ; // [object Boolean] 4 Object.prototype.toString.call(Symbol()); //[object Symbol] 5 Object.prototype.toString.call(undefined) ; // [object Undefined] 6 Object.prototype.toString.call(null) ; // [object Null] 7 Object.prototype.toString.call(new Function()) ; // [object Function] 8 Object.prototype.toString.call(new Date()) ; // [object Date] 9 Object.prototype.toString.call([]) ; // [object Array] 10 Object.prototype.toString.call(new RegExp()) ; // [object RegExp] 11 Object.prototype.toString.call(new Error()) ; // [object Error] 12 Object.prototype.toString.call(document) ; // [object HTMLDocument] 13 Object.prototype.toString.call(window) ; //[object global] window 是全局对象 global 的引用
5.原生原型扩展函数
接下来我们就用到另外一个利器:Object.prototype.toString.call
这是对象的一个原生原型扩展函数,用来更精确的区分数据类型。
我们来试试这个玩儿意儿:
var gettype=Object.prototype.toString
gettype.call('aaaa') 输出 [object String]
gettype.call(2222) 输出 [object Number]
gettype.call(true) 输出 [object Boolean]
gettype.call(undefined) 输出 [object Undefined]
gettype.call(null) 输出 [object Null] gettype.call({}) 输出 [object Object] gettype.call([]) 输出 [object Array] gettype.call(function(){}) 输出 [object Function] 看到这里,刚才的问题我们解决了
gettype封装的方法如下 : var gettype=Object.prototype.toString var utility={ isObj:function(o){ return gettype.call(o)=="[object Object]"; }, isArray:function(o){ return gettype.call(o)=="[object Array]"; }, isNULL:function(o){ return gettype.call(o)=="[object Null]"; }, isDocument:function(){ return gettype.call(o)=="[object Document]"|| [object HTMLDocument]; } ........ }