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基本编码模式小结
May 23 Javascript
UI Events 用户界面事件
Jun 27 Javascript
使用jQuery插件创建常规模态窗口登陆效果
Aug 23 Javascript
在JavaScript中使用NaN值的方法
Jun 05 Javascript
jQuery 获取跨域XML(RSS)数据的相关总结分析
May 18 Javascript
详解JavaScript节流函数中的Throttle
Jul 16 Javascript
深入理解JS实现快速排序和去重
Oct 17 Javascript
JavaScript基础——使用Canvas绘图
Nov 02 Javascript
jQuery条件分页 代替离线查询(附代码)
Aug 17 jQuery
JS设计模式之策略模式概念与用法分析
Feb 05 Javascript
Vue 中对图片地址进行拼接的方法
Sep 03 Javascript
js实现时钟定时器
Mar 26 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
PHP中的命名空间详细介绍
2015/07/02 PHP
变量在 PHP7 内部的实现(二)
2015/12/21 PHP
PHP通过引用传递参数用法分析
2016/12/01 PHP
浅谈htmlentities 、htmlspecialchars、addslashes的使用方法
2016/12/09 PHP
ubutu 16.04环境下,PHP与mysql数据库,网页登录验证实例讲解
2017/07/20 PHP
为Plesk PHP7启用Oracle OCI8扩展方法总结
2019/03/29 PHP
thinkphp5+layui实现的分页样式示例
2019/10/08 PHP
Javascript开发之三数组对象实例介绍
2012/11/12 Javascript
纯JS实现动态时间显示代码
2014/02/08 Javascript
jQuery+ajax实现鼠标单击修改内容的思路
2014/06/29 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
2016/05/17 Javascript
更靠谱的H5横竖屏检测方法(js代码)
2016/09/13 Javascript
vue router-link传参以及参数的使用实例
2017/11/10 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
2017/11/22 Javascript
Vue表单输入绑定的示例代码
2018/11/01 Javascript
微信小程序bindinput与bindsubmit的区别实例分析
2019/04/17 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
使用vue cli4.x搭建vue项目的过程详解
2020/05/08 Javascript
微信小程序实现多行文字滚动
2020/11/18 Javascript
python处理数据,存进hive表的方法
2018/07/04 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
详解django自定义中间件处理
2018/11/21 Python
python批量修改文件夹及其子文件夹下的文件内容
2019/03/15 Python
Python实现图像的垂直投影示例
2020/01/17 Python
基于梯度爆炸的解决方法:clip gradient
2020/02/04 Python
大数据分析用java还是Python
2020/07/06 Python
html5+css3之动画在webapp中的应用
2014/11/21 HTML / CSS
时装界的“朋克之母”:Vivienne Westwood
2017/07/06 全球购物
美国第二大连锁书店:Books-A-Million
2017/12/28 全球购物
聚网科技C++面试笔试题
2015/09/01 面试题
党员培训思想汇报
2014/01/07 职场文书
诚信承诺书模板
2014/05/26 职场文书
论文答谢词
2015/01/20 职场文书
2019朋友新婚祝福语精选
2019/10/10 职场文书
关于CentOS 8 搭建MongoDB4.4分片集群的问题
2021/10/24 MongoDB
SQL解决未能删除约束问题drop constraint
2022/05/30 SQL Server