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的图片的切换(以数字的形式)
Feb 14 Javascript
基于jquery实现漂亮的动态信息提示效果
Aug 02 Javascript
JavaScript Math.ceil() 函数使用介绍
Dec 11 Javascript
node.js插件nodeclipse安装图文教程
Oct 19 Javascript
Vue.JS入门教程之自定义指令
Dec 08 Javascript
微信小程序开发经验总结(推荐)
Jan 11 Javascript
Bootstrap面板使用方法
Jan 16 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
Aug 22 Javascript
vue 录制视频并压缩视频文件的方法
Jul 27 Javascript
Javascript格式化并高亮xml字符串的方法及注意事项
Aug 13 Javascript
vue实现axios图片上传功能
Aug 20 Javascript
解决Element中el-date-picker组件不回填的情况
Nov 07 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判断字符以及字符串的包含方法属性
2008/08/30 PHP
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
2013/06/03 PHP
php代码书写习惯优化小结
2013/06/20 PHP
PHP中for循环与foreach的区别
2017/03/06 PHP
JavaScript中的Window窗口对象
2008/01/16 Javascript
javascript 全角转换实现代码
2009/07/17 Javascript
javascript下高性能字符串连接StringBuffer类
2010/08/16 Javascript
js整数字符串转换为金额类型数据(示例代码)
2013/12/26 Javascript
javascript实现数字验证码的简单实例
2014/02/10 Javascript
巧用replace将文字表情替换为图片
2014/04/17 Javascript
jQuery基础知识小结
2014/12/22 Javascript
javascript中clipboardData对象用法详解
2015/05/13 Javascript
jQuery插件expander实现图片翻转特效
2015/05/21 Javascript
小程序开发实战:实现九宫格界面的导航的代码实现
2017/01/19 Javascript
设置cookie指定时间失效(实例代码)
2017/05/28 Javascript
JS滚动到指定位置导航栏固定顶部
2017/07/03 Javascript
js移动端事件基础及常用事件库详解
2017/08/15 Javascript
vue使用$emit时,父组件无法监听到子组件的事件实例
2018/02/26 Javascript
react写一个select组件的实现代码
2019/04/03 Javascript
JS实现京东商品分类侧边栏
2020/12/11 Javascript
Python对列表去重的多种方法(四种方法)
2017/12/05 Python
Python3.5实现的三级菜单功能示例
2019/03/25 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
Django中使用CORS实现跨域请求过程解析
2019/08/05 Python
Django url,从一个页面调到另个页面的方法
2019/08/21 Python
Web时代变迁及html5与html4的区别
2016/01/06 HTML / CSS
Waterford美国官网:爱尔兰水晶制品品牌
2017/04/26 全球购物
美国特价机票专家:Airfarewatchdog
2018/01/24 全球购物
竞选宣传委员演讲稿
2014/05/24 职场文书
推广普通话共筑中国梦演讲稿
2014/09/21 职场文书
初婚未育证明样本
2014/10/24 职场文书
中学生勤俭节约倡议书
2015/04/29 职场文书
2015年科协工作总结
2015/05/19 职场文书
Python控制台输出俄罗斯方块的方法实例
2021/04/17 Python
HTML5 语义化标签(移动端必备)
2021/08/23 HTML / CSS
动作冒险《Hell Is Us》将采用虚幻5 消灭怪物探索王国
2022/04/13 其他游戏