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 相关文章推荐
Div Select挡住的解决办法
Aug 07 Javascript
js 遍历对象的属性的代码
Dec 29 Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
Sep 04 Javascript
JavaScript中双叹号!!作用示例介绍
Sep 21 Javascript
jQuery 中DOM 操作详解
Jan 13 Javascript
javascript常用正则表达式汇总
Jul 31 Javascript
JavaScript制作淘宝星级评分效果的思路
Jun 23 Javascript
JS日期对象简单操作(获取当前年份、星期、时间)
Oct 26 Javascript
bootstrap modal+gridview实现弹出框效果
Aug 15 Javascript
微信小程序排坑指南详解
May 23 Javascript
Vue实现底部侧边工具栏的实例代码
Sep 03 Javascript
从0搭建vue-cli4脚手架
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
上传文件先创建目录 再上传到目录里面去
2010/12/29 PHP
smarty简单分页的实现方法
2014/10/27 PHP
PHP实现对xml的增删改查操作案例分析
2017/05/19 PHP
PHP 中TP5 Request 请求对象的实例详解
2017/07/31 PHP
jQuery 动画基础教程
2008/12/25 Javascript
jQuery each()小议
2010/03/18 Javascript
匹配任意字符的正则表达式写法
2010/04/29 Javascript
js 手机号码合法性验证代码集合
2012/09/29 Javascript
Node.js实现数据推送
2016/04/14 Javascript
BootStrap的alert提示框的关闭后再显示怎么解决
2016/05/17 Javascript
JS小数运算出现多为小数问题的解决方法
2016/06/02 Javascript
jquery实现(textarea)placeholder自动换行
2016/12/22 Javascript
jQuery简单获取DIV和A标签元素位置的方法
2017/02/07 Javascript
Vue自定义指令封装节流函数的方法示例
2018/07/09 Javascript
trackingjs+websocket+百度人脸识别API实现人脸签到
2018/11/26 Javascript
webpack3.0升级4.0的方法步骤
2020/04/02 Javascript
小程序实现简单语音聊天的示例代码
2020/07/24 Javascript
Python中计算三角函数之cos()方法的使用简介
2015/05/15 Python
Python使用matplotlib绘制随机漫步图
2018/08/27 Python
python 制作网站小说下载器
2021/02/20 Python
html5使用canvas绘制太阳系效果
2014/12/15 HTML / CSS
欧洲最大的滑雪假期供应商之一:Sunweb Holidays
2018/01/06 全球购物
可打印的优惠券、杂货和优惠券代码:Coupons.com
2018/06/12 全球购物
Hunkemöller瑞士网上商店:欧洲最大的内衣品牌之一
2018/12/03 全球购物
涉外文秘个人求职的自我评价
2013/10/07 职场文书
环境科学专业个人求职的自我评价
2013/11/28 职场文书
办公室保洁员岗位职责
2013/12/02 职场文书
幼儿园消防演练方案
2014/02/13 职场文书
读书演讲主持词
2014/03/18 职场文书
入党综合考察材料
2014/06/02 职场文书
个人简历自荐信
2014/06/26 职场文书
2015年环境监察工作总结
2015/07/23 职场文书
奖学金申请书(范文)
2019/08/14 职场文书
新手初学Java List 接口
2021/07/07 Java/Android
python游戏开发Pygame框架
2022/04/22 Python
vue项目如何打包之项目打包优化(让打包的js文件变小)
2022/04/30 Vue.js