判断是否为一个数组
typeof
对于五种基础类型(除了null),都可以用typeof来判断,对于null,array,function,object会是什么结果呢?
<pre>
console.log(typeof null); //object
console.log(typeof []); //object
console.log(typeof {}); //object
console.log(typeof function(){}) //function
</pre>
jQuery.isArray方法的分析
<pre>
jQuery.isArray:
Array.isArray || function( obj ) {
return jQuery.type(obj) === “array”;
}
</pre>
<pre>
jQuery.type:
function( obj ) {
if ( obj == null ) {
return obj + “”;
}
return typeof obj === “object” || typeof obj === “function” ?
class2type[ toString.call(obj) ] || “object” :
typeof obj;
}
</pre>
可以看到jQuery.isArray先是试图调用原生的isArray方法,若没有就调用jQuery.type方法。
jQuery.type 先判断是否为null或undefined是就返回其字符串形式,否则先调用typeof判断是否为object或function,是的话调用class2type[ toString.call(obj) ]可以详细判断,否则调用原生typeof
还不明白去看这篇文章
instanceof
用于判断一个变量是否为某个对象的实例
<pre>
console.log([] instanceof Array); //true
</pre>
constructor
返回对创建此对象的数组函数的引用,即返回对象相对应的构造函数
<pre>
console.log([].constructor === Array); //true
console.log({}.constructor === Object); //true
console.log(“string”.constructor === String); //true
console.log((123).constructor === Number); //true
console.log(true.constructor === Boolean); //true
</pre>
问题
在不同 iframe 中创建的 Array 并不共享 prototype。
因为array属于引用型数据,传递过程仅传递地址,所以用instanceof和constructor判断的array,因为涉及了原型链,所以必须是在当前页面声明的
Object.prototype.toString
这种方法就是刚才的class2type[ toString.call(obj) ]的原理,淘宝的 kissy 也是使用这种方式
涉及prototype和call不懂的快去复习
<pre>
Object.prototype.toString.call([]) === “[object Array]” //true
Object.prototype.toString.call({}) === “[object Object]” //true
Object.prototype.toString.call(function(){}) === “[object Function]” //true
Object.prototype.toString.call(“1”) === “[object String]” //true
</pre>
ES5中isArray
目前浏览器基本都支持了ES5,所以这是判断数组的最好方法
<pre>
console.log( Array.isArray([]) ) //true
</pre>
总结
综上所述,考虑兼容性和效率问题,以及代码整洁,判断是否为数组的函数封装如下:
<pre>
function isArray(o){
return Array.isArray(o) || Object.prototype.toString.call(o) === “[object Array]”;
}
</pre>
练习
原生js实现一个判断数据类型的函数
更多前端杂谈和知识总结尽在Deacyn的修炼之路