JS判断数组四种实现方法详解


Posted in Javascript onJune 29, 2020

一、前言

如何判断一个对象或一个值是否是一个数组,在面试或工作中我们常常会遇到这个问题,既然出现频率高,想着还是做个整理,那么本文主要基于几种判断方式,以及方式判断的原理,是否存在问题展开讨论。

二、判断对象是否是数组的几种方式

1.通过instanceof判断

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

let a = [];
a instanceof Array; //true
let b = {};
b instanceof Array; //false

在上方代码中,instanceof运算符检测Array.prototype属性是否存在于变量a的原型链上,显然a是一个数组,拥有Array.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构造函数创建时才可行。

2.通过constructor判断

我们知道,实例的构造函数属性constructor指向构造函数,那么通过constructor属性也可以判断是否为一个数组。

let a = [1,3,4];
a.constructor === Array;//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

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

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

let a = [1,2,3]
Object.prototype.toString.call(a) === '[object Array]';//true

它强大的地方在于不仅仅可以检验是否为数组,比如是否是一个函数,是否是数字等等

//检验是否是函数
let a = function () {};
Object.prototype.toString.call(a) === '[object Function]';//true
//检验是否是数字
let b = 1;
Object.prototype.toString.call(a) === '[object Number]';//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

4.通过Array.isArray()判断

Array.isArray() 用于确定传递的值是否是一个数组,返回一个布尔值。

let a = [1,2,3]
Array.isArray(a);//true

简单好用,而且对于多全局环境,Array.isArray() 同样能准确判断,但有个问题,Array.isArray() 是在ES5中提出,也就是说在ES5之前可能会存在不支持此方法的情况。怎么解决呢?

三、判断数组方法的最终推荐

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

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

那么对于数组判断的几种方式也说完了,合理的推荐也给出了,有什么问题或者错误的地方欢迎大家支持

参考资料:

Determining with absolute accuracy whether or not a JavaScript object is an array

Array.isArray()---MDN

instanceof---MDN

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript函数详解
Nov 17 Javascript
JavaScript中Number.NEGATIVE_INFINITY值的使用详解
Jun 05 Javascript
异步JS框架的作用以及实现方法
Oct 29 Javascript
JQuery ztree带筛选、异步加载实例讲解
Feb 25 Javascript
解决jquery无法找到其他父级子集问题的方法
May 10 Javascript
微信开发 js实现tabs选项卡效果
Oct 28 Javascript
canvas学习之API整理笔记(二)
Dec 29 Javascript
vue.js事件处理器是什么
Mar 20 Javascript
JavaScript实现的贝塞尔曲线算法简单示例
Jan 30 Javascript
30分钟用Node.js构建一个API服务器的步骤详解
May 24 Javascript
jQuery pager.js 插件动态分页功能实例分析
Aug 02 jQuery
js实现金山打字通小游戏
Jul 24 Javascript
vue实现整屏滚动切换
Jun 29 #Javascript
vue实现页面切换滑动效果
Jun 29 #Javascript
微信小程序实现导航栏和内容上下联动功能代码
Jun 29 #Javascript
Vue.js中Line第三方登录api的实现代码
Jun 29 #Javascript
vue实现列表滚动的过渡动画
Jun 29 #Javascript
element跨分页操作选择详解
Jun 29 #Javascript
vue实现数字滚动效果
Jun 29 #Javascript
You might like
json的键名为数字时的调用方式(示例代码)
2013/11/15 PHP
php利用云片网实现短信验证码功能的示例代码
2017/11/18 PHP
js资料toString 方法
2007/03/13 Javascript
用JTrackBar实现的模拟苹果风格的滚动条
2007/08/06 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
JavaScript中__proto__与prototype的关系深入理解
2012/12/04 Javascript
js导入导出excel(实例代码)
2013/11/25 Javascript
PhotoShop给图片自动添加边框及EXIF信息的JS脚本
2015/02/15 Javascript
使用AngularJS来实现HTML页面嵌套的方法
2015/06/17 Javascript
JavaScript实现搜索框的自动完成功能(一)
2016/02/25 Javascript
js密码强度实时检测代码
2016/03/02 Javascript
用jquery的attr方法实现图片切换效果
2017/02/05 Javascript
JS中如何实现Laravel的route函数详解
2017/02/12 Javascript
mui 打开新窗口的方式总结及注意事项
2017/08/20 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
React.js组件实现拖拽排序组件功能过程解析
2020/04/27 Javascript
在Vue中创建可重用的 Transition的方法
2020/06/02 Javascript
[01:44]剑指西雅图 展望TI之CIS战队专访
2014/06/25 DOTA
使用python分析git log日志示例
2014/02/27 Python
python解析xml文件操作实例
2014/10/05 Python
django admin添加数据自动记录user到表中的实现方法
2018/01/05 Python
基于python log取对数详解
2018/06/08 Python
pygame游戏之旅 游戏中添加显示文字
2018/11/20 Python
python机器学习库scikit-learn:SVR的基本应用
2019/06/26 Python
Python hashlib常见摘要算法详解
2020/01/13 Python
TensorFlow tensor的拼接实例
2020/01/19 Python
Python matplotlib读取excel数据并用for循环画多个子图subplot操作
2020/07/14 Python
Bally巴利英国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/05/07 全球购物
毕业生个人投资创业计划书
2014/01/04 职场文书
老总助理工作岗位职责
2014/02/06 职场文书
党的群众路线教育实践活动心得体会
2014/03/03 职场文书
大学生操行评语大全
2014/12/31 职场文书
教师读书活动心得体会
2016/01/14 职场文书
导游词之烟台威海蓬莱
2019/11/14 职场文书
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
2022/06/14 MySQL
Java Spring读取和存储详细操作
2022/08/05 Java/Android