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 相关文章推荐
Opacity.js
Jan 22 Javascript
几个高效,简洁的字符处理函数
Apr 12 Javascript
jQuery表单验证插件formValidator(改进版)
Feb 03 Javascript
JavaScript实现网页加载进度条代码超简单
Sep 21 Javascript
Vue和Bootstrap的整合思路详解
Jun 30 Javascript
静态页面实现 include 引入公用代码的示例
Sep 25 Javascript
JavaScript实现离开页面前提示功能【附jQuery实现方法】
Sep 26 jQuery
vue脚手架中配置Sass的方法
Jan 04 Javascript
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
May 22 Javascript
深入理解与使用keep-alive(配合router-view缓存整个路由页面)
Sep 25 Javascript
一个小时快速搭建微信小程序的方法步骤
Apr 15 Javascript
vue-i18n实现中英文切换的方法
Jul 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
PHP中return 和 exit 、break和contiue 区别与用法
2012/04/09 PHP
ThinkPHP3.1之D方法实例详解
2014/06/20 PHP
laravel实现简单用户权限的示例代码
2019/05/28 PHP
基于jquery的滚动鼠标放大缩小图片效果
2011/10/27 Javascript
基于javascript 闭包基础分享
2013/07/10 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
qq悬浮代码(兼容各个浏览器)
2014/01/29 Javascript
innerHTML动态添加html代码和脚本兼容多个浏览器
2014/10/11 Javascript
js实现div层缓慢收缩与展开的方法
2015/05/11 Javascript
JS基于FileSystemObject创建一个指定路径的TXT文本文件
2015/08/05 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
浅谈React中组件间抽象
2018/01/27 Javascript
vue实现2048小游戏功能思路详解
2018/05/09 Javascript
Vue实现远程获取路由与页面刷新导致404错误的解决
2019/01/31 Javascript
vue - vue.config.js中devServer配置方式
2019/10/30 Javascript
原生JS实现记忆翻牌游戏
2020/07/31 Javascript
解决nuxt页面中mounted、created、watch执行两遍的问题
2020/11/05 Javascript
详解vue实现坐标拾取器功能示例
2020/11/18 Vue.js
[01:22:29]真视界:2019年国际邀请赛总决赛
2020/01/29 DOTA
Python只用40行代码编写的计算器实例
2017/05/10 Python
Python实现二维数组输出为图片
2018/04/03 Python
用python代码将tiff图片存储到jpg的方法
2018/12/04 Python
python命令行工具Click快速掌握
2019/07/04 Python
使用Python为中秋节绘制一块美味的月饼
2019/09/11 Python
什么是符号链接,什么是硬链接?符号链接与硬链接的区别是什么?
2014/01/19 面试题
计算机专业个人简短的自我评价
2013/10/23 职场文书
蟋蟀的住宅教学反思
2014/04/26 职场文书
小组名称和口号
2014/06/09 职场文书
创建绿色社区汇报材料
2014/08/22 职场文书
工作失误检讨书(经典集锦版)
2014/10/17 职场文书
分居协议书范本
2014/11/03 职场文书
2014年学校后勤工作总结
2014/12/06 职场文书
2015年行政人事工作总结
2015/05/21 职场文书
《走遍天下书为侣》教学反思
2016/02/22 职场文书
Django REST framework 限流功能的使用
2021/06/24 Python
实操Python爬取觅知网素材图片示例
2021/11/27 Python