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 相关文章推荐
通过jquery实现页面的动画效果(实例代码)
Sep 18 Javascript
Bootstrap和Java分页实例第一篇
Dec 23 Javascript
数组Array的排序sort方法
Feb 17 Javascript
jQuery实现百度登录框的动态切换效果
Apr 21 jQuery
微信小程序之多文件下载的简单封装示例
Jan 29 Javascript
Vue仿支付宝支付功能
May 25 Javascript
一个Vue页面的内存泄露分析详解
Jun 25 Javascript
详解vue-cli中模拟数据的两种方法
Jul 03 Javascript
微信小程序自定义组件实现tabs选项卡功能
Jul 14 Javascript
微信小程序顶部导航栏可滑动并选中放大
Dec 05 Javascript
Vue中import from的来源及省略后缀与加载文件夹问题
Feb 09 Javascript
react中hook介绍以及使用教程
Dec 11 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
无线电波是什么?它是怎样传输的?
2021/03/01 无线电
收音机鉴频器对声音的影响和频偏分析
2021/03/02 无线电
php公用函数列表[正则]
2007/02/22 PHP
PHP创建对象的六种方式实例总结
2019/06/27 PHP
拖动布局之保存布局页面cookies篇
2010/10/29 Javascript
40款非常棒的jQuery 插件和制作教程(系列二)
2011/11/02 Javascript
讲解JavaScript中for...in语句的使用方法
2015/06/03 Javascript
Bootstrap3制作自己的导航栏
2016/05/12 Javascript
移动端H5开发 Turn.js实现很棒的翻书效果
2016/06/20 Javascript
微信小程序 Record API详解及实例代码
2016/09/30 Javascript
JS弹出窗口的运用与技巧大全
2016/11/01 Javascript
bootstrap table 多选框分页保留示例代码
2017/03/08 Javascript
AngularJS中$http的交互问题
2017/03/29 Javascript
jquery.guide.js新版上线操作向导镂空提示jQuery插件(推荐)
2017/05/20 jQuery
vue-prop父组件向子组件进行传值的方法
2018/03/01 Javascript
Vue中多个元素、组件的过渡及列表过渡的方法示例
2019/02/13 Javascript
如何通过setTimeout理解JS运行机制详解
2019/03/23 Javascript
详细分析vue响应式原理
2020/06/22 Javascript
[00:44]TI7不朽珍藏III——军团指挥官不朽展示
2017/07/15 DOTA
浅谈Python中的闭包
2015/07/08 Python
基于python中pygame模块的Linux下安装过程(详解)
2017/11/09 Python
解决python中遇到字典里key值为None的情况,取不出来的问题
2018/10/17 Python
pycham查看程序执行的时间方法
2018/11/29 Python
python使用time、datetime返回工作日列表实例代码
2019/05/09 Python
python 梯度法求解函数极值的实例
2019/07/10 Python
Python ADF 单位根检验 如何查看结果的实现
2020/06/03 Python
PyInstaller运行原理及常用操作详解
2020/06/13 Python
python爬虫使用正则爬取网站的实现
2020/08/03 Python
利用纯css3实现的文字亮光特效的代码演示
2014/11/27 HTML / CSS
Artist Guitars新西兰:乐器在线商店
2017/09/17 全球购物
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
监察建议书范文
2014/03/12 职场文书
大学应届毕业生求职信
2014/05/24 职场文书
2014年酒店工作总结范文
2014/11/17 职场文书
《狮子和鹿》教学反思
2016/02/16 职场文书
canvas多重阴影发光效果实现
2021/04/20 Javascript