typeof
typeof是最基础的判断对象类型的方法,下面通过一张表格列举出typeof判断不同对象的返回结果,从中我们可以发现typeof存在一些缺陷☛
表达式 | 返回值 |
---|---|
typeof 0; | ‘number’ |
typeof true; | ‘boolean’ |
typeof ‘abc’; | ‘string’ |
typeof function(){} | ‘function’ |
typeof undefined; | ‘undefined’ |
typeof unknownvariable; | ‘undefined’ |
typeof null | ‘object’ |
typeof {} | ‘object’ |
typeof [] | ‘object’ |
typeof symbol | ‘symbol’ |
(1)typeof只能准确的判断number、boolean、string、function、undefined、symbol(es6新增)。 | |
(2)宿主对象(JS环境提供的,比如浏览器) Implementation-dependent (js对象) | |
(3)判断某个全局变量是否存在用typeof window.myVar === ‘undefined’; | |
(4)函数内部判断某个变量是否存在用typeof myVar === ‘undefined’; | |
(5)判断null和数组[ ]都返回object,因此typeof无法区分null和数组。针对这两种类型给出下列解决办法: |
- 判断null使用
myVar === null;
- 判断Array方法
1. Array.isArray(arr);
Array 的实例没有 isArray 这个方法,所以它不存在于 Array 的原型链中也不是在构造函数内部定义的。它是 Array 类的静态方法。
var arr =[];
Array.isArray(arr);//true
2. 根据原型链
1)instanceof
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。判断是否为该对象的实例,object instanceof constructor。
[] instanceof Array; // true
[] instanceof Object; // true
[] instanceof RegExp; // false
new Date instanceof Date; // true
var simpleStr = "This is a simple string";
simpleStr instanceof String; // 返回 false, 检查原型链会找到 undefined
var myNonObj = Object.create(null);
myNonObj instanceof Object; // 返回 false, 一种创建非 Object 实例的对象的方法
2)constructor
在JavaScript中,每个对象都有一个constructor属性,它引用了实例化该对象的构造函数,常用于判断未知对象的类型。判断数组的函数也可以这样用:
function isArray(arr){
return typeof arr == "object" && arr.constructor == Array;
}
注意:在改变对象 obj 的原型链的情况下,constructor属性有可能被修改的,Foo.prototype 属性的值也有可能改变,这些都会导致检测出的结果不正确。
很多情况下,我们可以使用instanceof运算符或对象的constructor属性来检测对象是否为数组。例如很多JavaScript框架就是使用这两种方法来判断对象是否为数组类型。 但是检测在跨框架(cross-frame)页面中的数组时,会失败。原因就是在不同框(iframe)中创建的数组不会相互共享其prototype属性。例如:
<script>
window.οnlοad=function(){
var iframe_arr=new window.frames[0].Array;
alert(iframe_arr instanceof Array); // false
alert(iframe_arr.constructor == Array); // false
}
</script>
- Object.prototype.toString();
在Ajaxian上看到了一种精确的检测方法,跨原型链调用toString()方法:Object.prototype.toString()。可以解决上面的跨框架问题。 当Object.prototype.toString(o)执行后,会执行以下步骤: (学习参考)
1)获取对象o的class属性。
2)连接字符串:“[object “+结果(1)+”]”
3)返回 结果(2)
Object.prototype.toString.call([]); // 返回 “[object Array]”
Object.prototype.toString.call(/reg/ig); // 返回 “[object RegExp]”
这样,我们就可以写一个健壮的判断对象是否为数组的函数:
function isArray(arr){
return Object.prototype.toString.call(arr) === "[object Array]";
}
总结:
你可以通过Array.isArray(myObj) 或者Object.prototype.toString.call(myObj) === “[object Array]” 来安全的检测传过来的对象是否是一个数组。也可以用instanceof运算符和constructor属性结合typeof使用。
拓展:
jQuery中的 $.type接口
$.type(obj) ;
$.isArray(obj);
$.isFunction(obj);
$.isPlainObject(obj);