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闭包
Dec 14 Javascript
JavaScript高级程序设计 读书笔记之八 Function类及闭包
Feb 27 Javascript
jQuery往textarea中光标所在位置插入文本的方法
Jun 26 Javascript
jQuery时间插件jquery.clock.js用法实例(5个示例)
Jan 14 Javascript
js解决movebox移动问题
Mar 29 Javascript
jQuery 中的 DOM 操作
Apr 26 Javascript
jQuery Easyui 下拉树组件combotree
Dec 16 Javascript
Javascript创建类和对象详解
May 31 Javascript
解决vue无法设置滚动位置的问题
Oct 07 Javascript
详解JavaScript中的坐标和距离
May 27 Javascript
原生JavaScript实现日历功能代码实例(无引用Jq)
Sep 23 Javascript
p5.js临摹旋转爱心
Oct 23 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 smarty模版引擎中的缓存应用
2009/12/11 PHP
PHP类继承 extends使用介绍
2014/01/14 PHP
php生成随机数的三种方法
2014/09/10 PHP
PHP实现的简单三角形、矩形周长面积计算器分享
2014/11/18 PHP
PHP中$this和$that指针使用实例
2015/01/06 PHP
php压缩和解压缩字符串的方法
2015/03/14 PHP
PHP函数nl2br()与自定义函数nl2p()换行用法分析
2016/04/02 PHP
javascript之ESC(第二类混淆)
2007/05/06 Javascript
jquery struts 验证唯一标识(公用方法)
2013/03/27 Javascript
javascript自动改变文字大小和颜色的效果的小例子
2013/08/02 Javascript
JSP跨iframe如何传递参数实现代码
2013/09/21 Javascript
angularjs实现简单的购物车功能
2017/09/21 Javascript
Vue手把手教你撸一个 beforeEnter 钩子函数
2018/04/24 Javascript
JavaScript函数节流和函数去抖知识点学习
2018/07/31 Javascript
angularJs select绑定的model取不到值的解决方法
2018/10/08 Javascript
angularJS实现不同视图同步刷新详解
2018/10/09 Javascript
layui富文本编辑器前端无法取值的解决方法
2019/09/18 Javascript
Vue脚手架编写试卷页面功能
2020/03/17 Javascript
vue二选一tab栏切换新做法实现
2021/01/19 Vue.js
[01:04:05]Mineski vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
[41:52]DOTA2-DPC中国联赛 正赛 CDEC vs Dynasty BO3 第二场 2月22日
2021/03/11 DOTA
python 列表,数组和矩阵sum的用法及区别介绍
2018/06/28 Python
Python查找最长不包含重复字符的子字符串算法示例
2019/02/13 Python
使用Python实现 学生学籍管理系统
2019/11/26 Python
详解HTML5表单新增属性
2016/12/21 HTML / CSS
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
美国中西部家用医疗设备商店:Med Mart(轮椅、踏板车、升降机等)
2019/04/26 全球购物
Why do we need Unit test
2013/01/03 面试题
航空大学应届生求职信
2013/11/10 职场文书
编辑找工作求职信分享
2014/01/03 职场文书
高一政治教学反思
2014/01/28 职场文书
小学生学雷锋演讲稿
2014/04/25 职场文书
朋友聚会开场白
2015/06/01 职场文书
消费者投诉书范文
2015/07/02 职场文书
Html5通过数据流方式播放视频的实现
2021/04/27 HTML / CSS
nginx 配置缓存
2022/05/11 Servers