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操作XML 使用百度RSS作为新闻源示例
Feb 17 Javascript
自动刷新网页,自动刷新当前页面,JS调用
Jun 24 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
Feb 08 Javascript
js生成验证码并直接在前端判断
May 15 Javascript
js 判断登录界面的账号密码是否为空
Feb 08 Javascript
JavaScript组件开发之输入框加候选框
Mar 10 Javascript
js+canvas实现动态吃豆人效果
Mar 22 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
Apr 17 Javascript
解决VUEX刷新的时候出现数据消失
Jul 03 Javascript
实例详解JavaScript中setTimeout函数的执行顺序
Jul 12 Javascript
BootStrap Fileinput上传插件使用实例代码
Jul 28 Javascript
如何从头实现一个node.js的koa框架
Jun 17 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
rrmdir php中递归删除目录及目录下的文件
2011/05/15 PHP
php常用的安全过滤函数集锦
2014/10/09 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
2019/10/16 PHP
JS 显示当前日期与时间的代码
2010/03/24 Javascript
js 数值项目的格式化函数代码
2010/05/14 Javascript
新鲜出炉的js tips提示效果
2011/04/03 Javascript
js中Math之random,round,ceil,floor的用法总结
2013/12/26 Javascript
javascript 获取iframe里页面中元素值的方法
2014/02/17 Javascript
jQuery插件pagination实现无刷新分页
2016/05/21 Javascript
JS表格组件BootstrapTable行内编辑解决方案x-editable
2016/09/01 Javascript
JS实现滑动门效果的方法详解
2016/12/19 Javascript
js cookie实现记住密码功能
2017/01/17 Javascript
图文详解Javascript中的上下文和作用域
2017/02/15 Javascript
详解Angular CLI + Electron 开发环境搭建
2017/07/20 Javascript
angularJs提交文本框数据到后台的方法
2018/10/08 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
在小程序中推送模板消息的实现方法
2019/07/22 Javascript
vue实现简单学生信息管理
2020/05/30 Javascript
js实现简单扫雷
2020/11/27 Javascript
JavaScript实现通讯录功能
2020/12/27 Javascript
python代码 if not x: 和 if x is not None: 和 if not x is None:使用介绍
2016/09/21 Python
Python排序算法之选择排序定义与用法示例
2018/04/29 Python
Python后台开发Django的教程详解(启动)
2019/04/08 Python
python操作excel让工作自动化
2019/08/09 Python
Python如何调用JS文件中的函数
2019/08/16 Python
Python大批量搜索引擎图像爬虫工具详解
2020/11/16 Python
Python3 + Appium + 安卓模拟器实现APP自动化测试并生成测试报告
2021/01/27 Python
不同浏览器对CSS3和HTML5的支持状况
2009/10/31 HTML / CSS
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
2014年小班元旦活动方案
2014/02/16 职场文书
物业保安员岗位职责
2014/03/14 职场文书
女方家长婚礼致辞
2015/07/27 职场文书
CSS实现五种常用的2D转换
2021/12/06 HTML / CSS
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python
Java中的继承、多态以及封装
2022/04/11 Java/Android