JS判断数组四种实现方法详解

一、前言

如何判断一个对象或一个值是否是一个数组,在面试或工作中我们常常会遇到这个问题,既然出现频率高,想着还是做个整理,那么本文主要基于几种判断方式,以及方式判断的原理,是否存在问题展开讨论。

二、判断对象是否是数组的几种方式

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js实现简单音乐播放器

    本文实例为大家分享了js实现音乐播放器的具体代码,供大家参考,具体内容如下 效果图: 可播放暂停继续播放,进度条可拖动,时间展示,声音调节 完整代码(直接拿来用) <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>audio功能开发</title> <style> * { margin:0; padding:0 } .music-ra

  • 基于JSON实现传输byte数组过程解析

    今晚上在编写udp传输文件的时候发现无法用JSON传输字节数组,试了很多种办法都会报错,最后查资料找到了Base64这个类,这个类可以将字节数组转为字符串,在JSON中传输以后可以再转化为字节数组. 写个小例子如下: package test; import java.util.Base64; public class testStringAndbyte { public static void main(String[] args) { // TODO Auto-generated metho

  • js实现从右往左匀速显示图片(无缝轮播)

    本文实例为大家分享了js实现从右往左匀速显示图片的具体代码,供大家参考,具体内容如下 前言: 匀速显示图片,一般用于重复显示公司活动系列图片 背景图片: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <style type="text/css"> *{ margin: 0; padding: 0; } .

  • JavaScript之appendChild、insertBefore和insertAfter使用说明

    appendChild定义 appendChild(newChild: Node) : Node Appends a node to the childNodes array for the node. Supported: IE 5.0+, Mozilla 1.0+, Netscape 6.0+, Safari 1.0+, Opera 7.0+ 添加一个节点到指定的节点的子节点数组中,读起来好象有点拗口,简单地说就是将元素添加到指定的节点中 appendChild用法 target.appen

  • javascript insertAfter()定义与用法示例

    本文实例讲述了javascript insertAfter()定义与用法.分享给大家供大家参考,具体如下: HTML部分: <div id="b">bbbbbbbbb</div> <div>dddddd</div> JavaScript部分: window.onload=function(){ var a =document.createElement("span"); var b =document.createTe

  • Javascript insertAfter() 实现函数代码

    复制代码 代码如下: //DOM没有提供insertAfter()方法 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement) { // 如果最后的节点是目标元素,则直接添加.因为默认是最后 parent.appendChild(newElement); } else { parent.insertB

  • Json实现传值到后台代码实例

    1.定义一个键值对对象 function ObjData(key,value){ this.Key=key; this.Value=value; } 2.在点击表单的提交buttom的方法中: var list=document.getElementById("myForm").getElementsByTagName("input");//查询form下的所有input标签 var array=[]; //定义一个对象数据 存放每一个input的键值对(input

  • JavaScript缺少insertAfter解决方案

    在现有的方法后插入一个新元素,你可能会想:既然有insertBefore方法,是不是也有一个相应的insertAfter()方法.很可惜,DOM没有提供方法. 下面编写insertAfter函数,虽然DOM本身没有提供,但它确实提供了一个把一个节点插入到另一个节点之后所有工具.我们完全可以利用已有的DOM方法和属性编写一个insertAfter函数: <!DOCTYPE html> <html lang="en"> <head> <meta c

  • JS判断数组四种实现方法详解

    一.前言 如何判断一个对象或一个值是否是一个数组,在面试或工作中我们常常会遇到这个问题,既然出现频率高,想着还是做个整理,那么本文主要基于几种判断方式,以及方式判断的原理,是否存在问题展开讨论. 二.判断对象是否是数组的几种方式 1.通过instanceof判断 instanceof运算符用于检验构造函数的prototype属性是否出现在对象的原型链中的任何位置,返回一个布尔值. let a = []; a instanceof Array; //true let b = {}; b insta

  • buildAdmin开源项目引入四种图标方式详解

    目录 正文 引入Element-Plus图标库 引入Iconfont图标库 引入FontAwesome图标库 引入本地svg图标 正文 在项目开发中,我们经常使用可能都是UI组件库里的图标,当然由于业务需要,可能当前图标库没有我们需要的图标这时候就需要引入其它图标库的图标,比如iconfont.FontAweSome.本地图标库.在了解引入这些图标库之前,我们先学习一下各种图标库的引入使用: Element-Plus:由于elemen官方已经把图标封装成了组件,所以当我们引入图标的时候,需要全局

  • JS代码简洁方式之函数方法详解

    函数的参数越少越好 有一个准则是:如果你的函数参数超过两个,就应该改为对象传入. 这样做是合理的,因为当函数参数超过两个时,参数顺序开始变得难以记忆,而且容易出现一种很尴尬的情况:比如我只需要传入第三个参数,因为其自身顺序的原因,不得不补齐前两个根本用不上的参数,以让它顺利排在第三位. // bad const createArticle = (title, author, date, content) => { } createArticle('震惊,一男子竟偷偷干这事', 'zhangnan

  • JavaScript 对象的四种方式比较详解

    目录 前言 1. 引用比较 2. 手动比较 3. 浅层比较 4. 深层比较 5. 总结 前言 比较 JavaScript 中的值非常简单,只需用相等运算符即可,例如严格相等运算符: 'a' === 'c'; // => false 1 === 1; // => true 但是对象却有结构化的数据,所以比较起来比较困难.在本文中,你将学习如何正确比较 JavaScript 中的对象. 1. 引用比较 JavaScript 提供了 3 种方法来对值进行比较: 严格相等运算符 === 宽松相等运算符

  • Vue屏幕自适应三种实现方法详解

    目录 使用 scale-box 组件 设置设备像素比例(设备像素比) 通过JS设置zoom属性调整缩放比例 使用 scale-box 组件 属性: width宽度 默认1920 height高度 默认1080 bgc背景颜色 默认"transparent" delay自适应缩放防抖延迟时间(ms) 默认100 vue2版本:vue2大屏适配缩放组件(vue2-scale-box - npm) npm install vue2-scale-box 或者 yarn add vue2-sca

  • Android开发之基本控件和四种布局方式详解

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方式Android和iOS还是区别挺大的,在iOS中有Frame绝对布局和AutoLayout相对布局.而在Android中的布局方式就比较丰富了,今天博客中会介绍四种常用的布局方式.先总结一下控件,然后再搞一搞基本方式,开发环境还是用的Mac下的Android Studio.开始今天的正题, 虽然A

  • JS三目运算(三元运算)方法详解

    1.什么是三目运算:(布尔表达式 ? 值0:值1;) 5>3?alert('5大'):alert('3大'); 即    if(5>3){alert('5大')}else{alert('3大')}; 注意:三目运算和if(){}else{}的 区别是三目运算有返回值 例如: var max = a>b?a:b; 2.多条件的三目运算怎么写: 实例:根据学生成绩判定ABCD四个等级 var result = (sc<0 || sc>100) ?("分数无效"

  • JSP中九大内置对象和四种属性范围详解

    JSP中九大内置对象和四种属性范围详解 一般对象需要实例化才可以调用,而JSP的内置对象是不用实例化就可以直接调用的对象. 总共有9个,对应如下表: 序号 对象 类型 1 pageContext javax.servlet.jsp.PageContext 2 request javax.servlet.http.HttpServletRequest 3 response javax.servlet.http.HttpServletResponse 4 session javax.servlet.

  • Spring Data Jpa的四种查询方式详解

    这篇文章主要介绍了Spring Data Jpa的四种查询方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.调用接口的方式 1.基本介绍 通过调用接口里的方法查询,需要我们自定义的接口继承Spring Data Jpa规定的接口 public interface UserDao extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> 使用这

  • C#获取本地IP的四种方式示例详解

    1.第一种方式 采用System.Net.Dns的GetHostAddress的方式,具体请看代码: /// <summary> /// 网络不通畅可以获取 /// 不过能获取到具体的IP /// </summary> /// <returns></returns> public static List<IPAddress> GetByGetHostAddresses() { try { IPAddress[] adds = Dns.GetHos

随机推荐