JS判断是否为数组详解

JS判断是否为数组详解JS 判断是否为数组详解

此处提供可供验证的数据类型

let a = [1,2,3,4,5,6]; let b = [ { 
    name: '张飞', type: 'tank'}, { 
    name: '关羽', type: 'soldier'}, { 
    name: '刘备', type: 'shooter'}, ]; let c = 123; let d = 'www'; let e = { 
    name: '安琪拉', type: 'mage'}; 

Array.isArray()

Array.isArray()能判断一个元素是否为数组,如果是就返回true,否则就返回false

console.log(Array.isArray(a)); // true console.log(Array.isArray(b)); // true console.log(Array.isArray(c)); // false console.log(Array.isArray(d)); // false console.log(Array.isArray(e)); // false 

对于多全局环境(不了解可以此处略过,看下面的示例)Array.isArray() 同样能准确判断。

但有个问题,Array.isArray() 是在ES5中提出,也就是说在ES5之前可能会存在不支持此方法的情况。怎么解决呢?看到最后,自然就清楚了。

通过instanceof判断

instanceof运算符用于检验构造函数的prototype属性是否出现在对象的原型链中的任一位置,返回一个布尔值。

console.log(a instanceof Array); // true console.log(b instanceof Array); // true console.log(c instanceof Array); // false console.log(d instanceof Array); // false console.log(e instanceof Array); // false 

判断是否为数组就是检测Arrray.prototype属性是否存在于变量数组(a,b)的原型链上,显然a,b为数组,拥有Arrray.prototype属性,所以为true

存在问题:
需要注意的是,prototype属性是可以修改的,所以并不是最初判断为true就一定永远为真。

其次,当我们的脚本拥有多个全局环境,例如html中拥有多个iframe对象,instanceof的验证结果可能不会符合预期,例如:

//为body创建并添加一个iframe对象 var iframe = document.createElement('iframe'); document.body.appendChild(iframe); //取得iframe对象的构造数组方法 xArray = window.frames[0].Array; //通过构造函数获取一个实例 var arr = new xArray(1,2,3); arr instanceof Array;//false 

导致这种问题是因为iframe会产生新的全局环境,它也会拥有自己的Array.prototype属性,让不同环境下的属性相同很明显是不安全的做法,所以Array.prototype !== window.frames[0].Array.prototype,想要arr instanceof Array为true,你得保证arr是由原始Array构造函数创建时才可行。

通过对象构造函数的constructor判断

Obiect的每个实例都有构造函数constructor,保存着创建每个对象的函数。

console.log(a.constructor === Array); // true console.log(b.constructor === Array); // true 

以下包含判断其它的数据类型验证

console.log(c.constructor === Number); // true console.log(d.constructor === String); // true console.log(e.constructor === Object); // true 

同样,这种判断也会存在多个全局环境的问题,导致的问题与instanceof相同。

//为body创建并添加一个iframe标签 var iframe = document.createElement('iframe'); document.body.appendChild(iframe); //取得iframe对象的构造数组方法 xArray = window.frames[window.frames.length-1].Array; //通过构造函数获取一个实例 var arr = new xArray(1,2,3); arr.constructor === Array;//false 

通过Object.prototype.toString.call()判断

通过原型链查找调用

Object.prototype.toString().call()可以获取到对象的不同类型,例如

console.log(Object.prototype.toString.call(a) === '[object Array]'); // true console.log(Object.prototype.toString.call(b) === '[object Array]'); // true 

以下包含判断其它的数据类型验证

console.log(Object.prototype.toString.call(c) === '[object Number]'); // true console.log(Object.prototype.toString.call(d) === '[object String]'); // true console.log(Object.prototype.toString.call(e) === '[object Object]'); // true 

甚至对于多全局环境时, Object.prototype.toString().call()也能符合预期处理判断。

//为body创建并添加一个iframe标签 var iframe = document.createElement('iframe'); document.body.appendChild(iframe); //取得iframe对象的构造数组方法 xArray = window.frames[window.frames.length-1].Array; //通过构造函数获取一个实例 var arr = new xArray(1,2,3); console.log(Object.prototype.toString.call(arr) === '[object Array]');//true 

通过对象原型链上的isPrototypeOf()判断

Array.prototype属性为Array的构造函数原型,里面包含有一个方法 isPrototypeOf() 用于测试一个对象是否存在于;另一个对象的原型链上。

console.log(Array.prototype.isPrototypeOf(a)); // true console.log(Array.prototype.isPrototypeOf(b)); // true console.log(Array.prototype.isPrototypeOf(c)); // false console.log(Array.prototype.isPrototypeOf(d)); // false console.log(Array.prototype.isPrototypeOf(e)); // false 

最终方法

当然还是用Array.isArray(),从ES5新增isArray()方法正是为了提供一个稳定可用的数组判断方法,不可能专门为此提出的好东西不用,而对于ES5之前不支持此方法的问题,我们其实可以做好兼容进行自行封装,像这样:

if (!Array.isArray) { 
     Array.isArray = function(arg) { 
     return Object.prototype.toString.call(arg) === '[object Array]'; }; } 


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/211111.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午11:11
下一篇 2026年3月18日 下午11:11


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号