原文:http://www.cnblogs.com/zichi/p/5103842.html
在 Javascript 中,如何判断一个变量是否是数组?
最好的方式是用 ES5 提供的 Array.isArray()
方法(毕竟原生的才是最屌的):
var a = [0, 1, 2];
console.log(Array.isArray(a)); // true
但是鉴于低版本 IE 不支持 ES5,如需兼容,需要想想别的办法。
typeof
?
我们都知道,数组是特殊的对象,所以数组的 typeof 结果也是 object,而因为 null 的结果也是 object,所以如需用 typeof 运算符来判断数组,需要这么写:
var a = [0, 1, 2];
// 是 object 同时排除 null、排除纯对象
console.log(typeof a === 'object' && a !== null && Object.prototype.toString.call(a) !== '[object Object]'); // true
instanceof
?
来回忆下 instanceof 运算符的使用方式。a instanceof b,如果返回 true,表示 a 是 b 的一个实例。那么如果 a instanceof Array 返回 true,是不是就说明 a 是 数组类型呢?跟 instanceof 师出同门的还有 constructor,是否同样可以判断呢?
var a = [0, 1, 2];
console.log(a instanceof Array); // true 就是数组?
console.log(a.constructor === Array); // true 数组?
答案是否定的,需要注意嵌套 frame 的情况。
index.htm 代码:
<iframe src='a.htm'></iframe>
<script>
window.onload = function() {
var a = window.frames[0].a;
console.log(a instanceof Array); // false
console.log(a.constructor === Array); // false
};
</script>
a.htm 代码:
<script>
window.a = [1, 2, 3];
</script>
我们看到 index.htm 代码中,变量 a 确实是一个数组,但是 a instanceof Array 的结果却是 false。
这是因为每个 frame 都有一套自己的执行环境,跨 frame 实例化的对象彼此不共享原型链。如果打印 a instanceof window.frames[0].Array,那么结果就是 true 了。
特性嗅探?
var a = [0, 1, 2];
if (a.sort) {
// 是数组
}
也不靠谱,万一某个对象正好有值为 sort 的 key 呢?
var a = {sort: 'me'};
if (a.sort) {
// 数组?
// 其实我真的不是数组
}
正确的姿势是使用 Object.prototype.toString() 判断:
var a = [0, 1, 2];
console.log(Object.prototype.toString.call(a) === '[object Array]'); // true
事实上,这也是一些类库进行数组(甚至其他类型)判断的主流方式。
比如在 jQuery 中进行数组判断的相关代码(PS:摘自 jQuery 1.10.1,最近版本的 jQuery 只保留了 Array.isArray(),没有对不支持 ES5 的浏览器做兼容):
isArray: Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
},
type: function( obj ) {
if ( obj == null ) {
return String( obj );
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ core_toString.call(obj) ] || "object" :
typeof obj;
},
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
代码很清晰,如支持原生的 Array.isArray(),则直接判断,不支持的话调用 toString() 进行判断。同时可以看到很多其他类型变量的判断也是基于 toString() 方法。当然这里说的 toString() 均是 Object 原型链上的 toString() 方法。
console.log(Object.prototype.toString.call(10)); // [object Number]
console.log(Object.prototype.toString.call('hello')); // [object String]
console.log(Object.prototype.toString.call(true)); // [object Boolean]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call({})); // [object Object]
console.log(Object.prototype.toString.call(function(){})); // [object Function]
console.log(Object.prototype.toString.call(/a/g)); // [object RegExp]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(new Date())); // [object Date]
Object.prototype.toString() 为何能返回这样类型的字符串?
ECMA-262:
Object.prototype.toString( ) When the toString method is called, the following steps are taken:
1. Get the [[Class]] property of this object.
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
3. Return Result (2)
上面的规范定义了 Object.prototype.toString 的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于 "[object Array]" 的字符串作为结果([[]]用来表示语言内部用到的、外部不可直接访问的属性,称为 "内部属性")。利用这个方法,再配合 call,我们可以取得任何对象的内部属性 [[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。还是先来看看在 ECMA 标准中 Array 的描述吧:
new Array([ item0[, item1 [,…]]])
The [[Class]] property of the newly constructed object is set to “Array”.
所以 Javascript 中判断数组的函数可以这样写:
function isArray(a) {
Array.isArray ? Array.isArray(a) : Object.prototype.toString.call(a) === '[object Array]';
}
相关推荐
Javascript中二维数组的遍历,上次碰到的时候有点迷惑,找了很多资料,最后整理的精华
javascript如何判断数组内元素是否重复的方法集锦
这份资源详细介绍了如何在JavaScript中判断数组是否包含某个值。文档中提供了多种实现方法,包括使用includes()函数、使用indexOf()函数、使用filter()函数等多种方式。每一种方法都有详细的代码示例和实现说明,让...
JavaScript数组(源代码)JavaScript数组(源代码)JavaScript数组(源代码)JavaScript数组(源代码)JavaScript数组(源代码)JavaScript数组(源代码)JavaScript数组(源代码)JavaScript数组(源代码)...
JavaScript中的数组特性介绍.docx
NULL 博文链接:https://wangweiwei358.iteye.com/blog/689840
以及与其相关的属性方法,以及事件处理程序,还注明了该对象或数组的父对象用户同样可能需要参考Online Companion中的超级文本Object Hierarchy页面(http://www.netscapepress.com/support/javascript/10-9.htm),以便...
javascript读取json数组生成滚动分页 javascript读取json数组生成滚动分页 javascript读取json数组生成滚动分页
javascript中FOREACH数组方法使用示例.docx
个人做的一个数组删除的方法,因实际需要就写了个,分享给大家吧!
主要介绍了JavaScript如何获取数组最大值和最小值,需要的朋友可以参考下
主要介绍了javascript判断数组内是否重复的方法,涉及javascript针对数组的相关操作技巧,非常具有实用价值,需要的朋友可以参考下
collect.js 是一个不依赖于任何第三方库,用于在JavaScript中处理数组和对象,其中有许多有用的功能,并且API(几乎)与 Laravel Collections 5.5相同
NULL 博文链接:https://rogerfederer.iteye.com/blog/783714
JavaScript实现筛选数组 本文实例为大家分享了JavaScript实现筛选数组的具体代码,供大家参考,具体内容如下 今天,运用JavaScript的相关知识,制作了筛选数组的案例。希望我们互相学习,共同进步! 最终效果图...
Javascript数组及其操作
我们交换数组可以实现元素上下移动了,这个效果我们在表格或以前排序算法中都会用到,下面来看一个JavaScript下实现交换数组元素上下移动例子 在写项目的时候,要实现一个数组记录上下移动的示例。写起来也没有没...
JavaScript对象与数组参考大全JavaScript语法结构
主要介绍了JavaScript遍历查找数组中最大值与最小值的方法,结合实例形式分析了javascript基于数组遍历、判断实现最大值与最小值计算的相关操作技巧,需要的朋友可以参考下