JavaScript判断数组类型的三种方法及跨框架解决方案
本文详解JavaScript中判断数组类型的三种常用方法:typeof、instanceof以及Object.prototype.toString。重点分析了前两种方法在跨iframe场景下的局限性,并推荐了基于Object.prototype.toString.call的健壮检测方案,该方案能准确识别各类内置对象类型,被jQuery等主流框架广泛采用。
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 运算符。
instanceof与constructor属性检测
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 属性。
在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> 基于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]";
} 该方法得到了多位国外JavaScript专家的认可,并将在即将发布的jQuery 1.3版本中用于数组检测。
prototype.js的一位维护者编写了以下函数,用于获取对象的类型名:
代码如下:
/**
* Returns internal [[Class]] property of an object
*
* Ecma-262, 15.2.4.2
* 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).
*
* __getClass(5); // => "Number"
* __getClass({}); // => "Object"
* __getClass(/foo/); // => "RegExp"
* __getClass(''); // => "String"
* __getClass(true); // => "Boolean"
* __getClass([]); // => "Array"
* __getClass(undefined); // => "Window"
* __getClass(Element); // => "Constructor"
*
*/
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)); // trueES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
