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 相关文章推荐
关于实现代码语法标亮 dp.SyntaxHighlighter
Feb 02 Javascript
基于jQuery的history历史记录插件
Dec 11 Javascript
JS实现匀速运动的代码实例
Nov 29 Javascript
JavaScript简单表格编辑功能实现方法
Apr 16 Javascript
WebApi+Bootstrap+KnockoutJs打造单页面程序
May 16 Javascript
AngularJS 入门教程之HTML DOM实例详解
Jul 28 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
Dec 28 Javascript
Reactjs实现通用分页组件的实例代码
Jan 19 Javascript
详解angularJs中关于ng-class的三种使用方式说明
Jun 02 Javascript
详解win7 cmd执行vue不是内部命令的解决方法
Jul 27 Javascript
微信小程序使用字体图标的方法
May 23 Javascript
nuxt静态部署打包相对路径操作
Nov 06 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
在smarty中调用php内置函数的方法
2013/02/07 PHP
详解php中curl返回false的解决办法
2019/03/18 PHP
PHP7匿名类的用法示例
2019/04/05 PHP
javascript实现 在光标处插入指定内容
2007/05/25 Javascript
jquery批量设置属性readonly和disabled的方法
2014/01/24 Javascript
JS实现div居中示例
2014/04/17 Javascript
jquery插件推荐 jquery.cookie
2014/11/09 Javascript
jQuery中insertBefore()方法用法实例
2015/01/08 Javascript
jQuery中noconflict函数的实现原理分解
2015/02/03 Javascript
基于jQuery实现以手风琴方式展开和折叠导航菜单
2016/01/28 Javascript
点击页面任何位置隐藏div的实现方法
2016/09/05 Javascript
JavaScript“尽快失败”的原则实例详解
2016/10/08 Javascript
JS实现图片点击后出现模态框效果
2017/05/03 Javascript
js实现放大镜特效
2017/05/18 Javascript
bootstrap手风琴折叠示例代码分享
2017/05/22 Javascript
简单实现js上传文件功能
2017/08/21 Javascript
Vue前端开发规范整理(推荐)
2018/04/23 Javascript
Node.js API详解之 dns模块用法实例分析
2020/05/15 Javascript
解决vue项目,npm run build后,报路径错的问题
2020/08/13 Javascript
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
python安装教程
2018/02/28 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
pytorch 自定义数据集加载方法
2019/08/18 Python
英国评分最高的女性剃须刀订阅盒:FFS Beauty
2018/01/25 全球购物
十佳大学生事迹材料
2014/01/29 职场文书
经典公益广告词
2014/03/13 职场文书
三关爱志愿服务活动方案
2014/08/17 职场文书
小学音乐教师个人工作总结
2015/02/05 职场文书
员工辞退通知书
2015/04/17 职场文书
青年文明号创建口号大全
2015/12/25 职场文书
使用pandas生成/读取csv文件的方法实例
2021/07/09 Python
SpringBoot整合RabbitMQ的5种模式实战
2021/08/02 Java/Android
Javascript的promise,async和await的区别详解
2022/03/24 Javascript
python疲劳驾驶困倦低头检测功能的实现
2022/04/04 Python
使用 DataAnt 监控 Apache APISIX的原理解析
2022/07/07 Servers
Docker部署Mysql8的实现步骤
2022/07/07 Servers