JavaScript判断数组的三种方法及跨框架检测方案

作者:半夏时间:2026-10-24 10:06:40浏览:380

本文详细解析JavaScript中判断数组类型的三种常用方法:typeof、instanceof及constructor属性,并指出它们在跨框架场景下的局限性。重点介绍通过Object.prototype.toString调用判断数组的健壮方案,该方案能准确识别跨iframe创建的数组,被jQuery等主流库采用。

1) typeof 运算符

typeof运算符的局限性

typeof是一个一元运算符,其返回值是描述操作数类型的字符串,可能的结果包括"number"、"string"、"boolean"、"object"、"function"以及"undefined"(后者常用于检测变量是否存在)。


然而,typeof的功能存在局限,对于Date和RegExp等特定类型,它统一返回"object"。例如:



typeof {}; // "object"


typeof []; // "object"


typeof new Date(); // "object"



因此,typeof仅在区分对象与原始类型时有效。若要区分不同类型的对象,必须借助其他方法,例如instanceof运算符或对象的constructor属性。



2)instanceof 运算符。

instancefront运算符的使用

instancefront运算符要求左侧操作数为对象,右侧为类名或构造函数。若左侧对象是右侧类或构造函数的实例,则返回true;若非实例或为null,则返回false。示例如下:



[] instanceof Array; // true


[] instanceof Object; // true


[] instanceof RegExp; // false


new Date instanceof Date; // true



基于此,可以使用instanceof来判断对象是否为数组:



function isArray(arr)


{

return arr instanceof Array;


}

3)constructor 属性。

constructor属性判断法

在JavaScript中,每个对象都拥有constructor属性,该属性引用了初始化该对象的构造函数,常用于判断未知对象的类型。若通过typeof确定值为对象,即可利用constructor属性判断其具体类型。因此,判断数组的函数也可实现为:



function isArray(arr)


{

return typeof arr == "object" && arr.constructor == Array;


}

在许多场景中,使用instanceof运算符或constructor属性来检测对象是否为数组是可行的,许多JavaScript框架也采用这两种方法。


但在跨框架(cross-frame)页面中检测数组时,上述方法会失效。原因是不同iframe中创建的数组不共享其prototype属性。例如:


跨框架检测的解决方案

代码如下:

 
<script>
window.onload=function(){
var iframe_arr=new window.frames[0].Array;
alert(iframe_arr instanceof Array); // false
alert(iframe_arr.constructor == Array); // false
} 
</script>
<body>
<iframe></iframe>
</body>

根据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]";
} 

该方法得到了国外多位JavaScript专家的认可,并在即将发布的jQuery 1.3版本中被用于数组检测。



prototype.js的一位维护者编写了以下函数,用于获取对象的类型名:



function __getClass(object)


{

return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];


};

以此为基础,可以扩展用于检测各种对象类型:


代码如下:

 
var is =
{ 
types : ["Array", "Boolean", "Date", "Number", "Object", "RegExp", "String", "Window", "HTMLDocument"]
} 
for(var i = 0, c; c = is.types[i ++ ]; )
{ 
is[c] = (function(type)
{ 
return function(obj)
{ 
return Object.prototype.toString.call(obj) == "[object " + type + "]";
} 
} 
})(c);
} 
alert(is.Array([])); // true
alert(is.Date(new Date)); // true
alert(is.RegExp(/reg/ig)); // true
作者最新文章