摘要:

1.数组检测的方法:

1) typeof 、

2) instanceof 、

3) constructor 、

4) Object.prototype.toString、

5) Array.isArray()。

以上为数组检测的方法,但是这些方法中:

Array.isArray()方法是最为简单方便的方法,但是存在版本支持性问题,没有版本支持性问题且较好的检测方法是使用Object.prototype.toString结合call()方法来检查,通常数组检测中我们常用的做法是两种方法结合。

原型链,在使用数组检测方法时我们要对原型链有深刻的理解,才能知道使用该数组检测方法的实际原理是什么。关于原型链的理解,可以看我写的这篇博客:http://www.cnblogs.com/novice007/p/7764583.html

构造函数,使用构造函数的方法检测数组,这是很大的一个坑,因为构造函数是能够被重写的,所以所得结果就不正确。例如:

1)var arr = [];

arr.constructor === Array; //返回true

2)var arr = 'abc';

arr.constructor = Array;

arr.constructor === Array;  //返回true

因为constructor能够被重写,所以从例2可以很明显的知道arr不是数组,但是它被数组重写了,所以返回true。

方法简介

1.typeof方法

typeof方法是判断数据的类型。在JavaScript中基本数据类型有number、null、Boolean、string、array、object、functionv、undefined等。其typeof()方法检测返回值分别为:

1)字符串(string),typeof()的返回值为string,例如typeof(‘97900’)==》返回string。

2)函数类型(function),typeof()的返回值为function,例如typeof(RegExp)==》返回function。

3)数组(array)、对象(object)、null,typeof()的返回值都为object,例如typeof(null)、typeof(document),typeof([1,3,4,8])==》返回object。

4)布尔类型(Boolean),typeof()的返回值为Boolean,例如typeof(true)==》返回Boolean。

5)数字类型,typeof()的返回值为number,例如typeof(1)==》返回number。

6)对于未定义的变量,typeof()检测结果都返回undefined。

说明:由上面typeof方法对各个数据类型的检测返回值可知typeof方法不能够准确的检测一个数据是否是数组,因为typeof方法对对象、数组、null的检测结果都是返回object,我们并不能够知道该数据是否为对象还是数组。从中我们也可以得知在使用 typeof 运算符时采用引用类型存储值会有一些问题,就是不管引用的是什么类型的对象,它都返回 “object”。

2.instanceof方法

instanceof方法是用来判断一个对象是否是当前类的一个实例,也可以在继承关系中用来判断一个实例是否属于它的父类型,返回值为true或false。如下例子:

1)console.log(Object instanceof Object);//true
console.log(Function instanceof Function);//true

console.log(Number instanceof Number);//false
console.log(String instanceof String);//false
console.log(Function instanceof Object);//true

2)instanceof方法在继承关系中用来判断一个实例是否属于它的父类型。

function A(){}

function B(){}

B.prototype = new A();//JavaScript 原型继承

var C = new B();

console.log(C instanceof B)//true

console.log(C instanceof A)//true

说明:这里大家可能比较好奇,为什么只有Object和function的instanceof返回值为true,其它的(a instanceof a)返回值都为false,对于这个问题,大家可以在https://www.ibm.com/developerworks/cn/web/1306_jiangjj_

jsinstanceof/这篇文章中看看,这篇文章中对instanceof的用法讲解的非常的清楚,这里我就不再说明。Instanceof用法用法很强大,但是instanceof也不是判断数组的好方法,原因我们再通过下面这个例子说明一下:

window.onload=function(){

Var iframe_arr=new window.frames[0].Array;

alert(iframe_arrinstanceof Array); //返回 false

}

出现这个问题的原因简单的说是因为在不同框架(iframe)中创建的数组不会相互共享其prototype属性。

原型链:

ECMAScript中对原型链的概念进行了描述,通过查阅了ECMAScript高级程序设计书,原型链的基本思想就是利用原型让一个引用类型继承另外一个引用类型的属性和方法。通俗的说原型链就是通过构造函数、原型与实例之间形成的一种链试关系,每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象内部的指针。对于更多的原型和原型链知识我就不在这里一一的说明了,大家可以通过查阅资料,进入更深的理解。

3.constructor 方法

使用constructor 方法判断数组的原理是因为每个实例都有与之对应的构造函数,我们可以通过判断它的构造函数,从而判断它属于哪个类型。但是该方法也存在不足,因为构造函数它能够被重写从而导致判断不正确,不仅如此constructor方法与instanceof方法也存在相同的问题,即在不同框架(iframe)中创建的数组不会相互共享其prototype属性。通过下面这个例子我们能够很明显的知道,该判断是错误的。

var arr = 'abc';

arr.constructor = Array;

arr.constructor === Array;  //返回true

4.Array.isArray() 方法

Array.isArray() 函数的返回值为Boolean类型,如果指定的参数是数组,则返回true,否则返回false。

var arr = [];

var res = Array.isArray(arr);// true

var arr = new Array();

var res = Array.isArray(arr);// true

var arr = [1, 2, 3];

var res = Array.isArray(arr);// true

var res = Array.isArray("an array");

document.write(res);//false

说明:该方法是很好的判断数组的方法,但是isArray() 在以下文档模式中不受支持:Quirks、Internet Explorer 6 标准模式、Internet Explorer 7 标准模式、Internet Explorer 8 标准模式。所以在使用isArray()时要做版本判断,该版本支持的时候就使用该方法,不支持的时候就使用object.prototype.to

String.call()方法,接下来将继续介绍object.prototype.toString.call()方法的使用。

5.object.prototype.toString.call() 方法

该方法的原理是通过toString()方法转换,直接输出对象的类型(class)属性。

1)判断基本类型:

Object.prototype.toString.call(null);//”[object Null]”

Object.prototype.toString.call(undefined);//”[object Undefined]”

Object.prototype.toString.call(“abc”);//”[object String]”

Object.prototype.toString.call(123);//”[object Number]”

Object.prototype.toString.call(true);//”[object Boolean]”

2)判断原生引用类型:

函数类型

Function fn(){console.log(“test”);}

Object.prototype.toString.call(fn);//”[object Function]”

日期类型

var date = new Date();

Object.prototype.toString.call(date);//”[object Date]”

数组类型

var arr = [1,2,3];

Object.prototype.toString.call(arr);//”[object Array]”

说明:这里大家可能会比较好奇,为什么不使用Object.toString呢?这是因为toString为Object的原型方法,而Array ,function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用Object.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。

总结

通过上面的简单讲解,我相信大家也能够清楚的知道,在数组判断中,最好的判断方法是Array.isArray() 方法和object.prototype.toString.call()方法,Array.isArray() 是最直接最简单数组判断方法,但是存在版本支持问题,所以在版本兼容的情况下我们就使用该方法。object.prototype.toString.call()方法也是很好的数组判断方法,它解决了跨iframe 失效的问题,并且不存在版本支持问题,但是使用object.prototype.toString.call()是我们假设object.prototype.toString没有被重写的理想情况,因为它也有可能被重写。所以通过一系列的判断与对比,得出了判断数组最好的办法。

var arr1 = [8,4,9];

var arr2 = [{ a : 1, b : 2 }];

function isArray(value){

if (typeof Array.isArray === "function") {

return Array.isArray(value);

}else{

return Object.prototype.toString.call(value) === "[object Array]";

}

}

alert(isArray(arr1));// true

alert(isArray(arr2));// true

Javascript中数组的判断方法的更多相关文章

  1. javascript中数组Array的方法

    一.常用方法(push,pop,unshift,shift,join)push pop栈方法,后进先出var a =[1,2,3];console.log(a.push(40)); //4 返回数组的 ...

  2. javascript中数组常用的方法和属性

    前言 在javascript中,数组是一种非常重要的数据类型,我们时常会和它打交道,最近在开发项目中频繁的使用到数组,但是自己对数组的众多方法已经是非常模糊了,为了方便自己以后能够更好的使用数组中的属 ...

  3. javascript中数组常用的方法

    在JavaScript中,数组可以使用Array构造函数来创建,或使用[]快速创建,这也是首选的方法.数组是继承自Object的原型,并且他对typeof没有特殊的返回值,他只返回'object'. ...

  4. javascript中数组的concat()方法 - 数组连接

    <html> <head> <title>数组的concat()方法</title> <script> /* 数组的concat()方法: ...

  5. 【前端_js】javascript中数组的map()方法

    数组的map()方法用于遍历数组,每遍历一个元素就调用回调方法一次,并将回调函数的返回结果作为新数组的元素,被遍历的数组不会被改变. 语法:let newAarray = arr.map(functi ...

  6. 一张图看懂JavaScript中数组的迭代方法:forEach、map、filter、reduce、every、some

    好吧,竟然不能单发一张图,不够200字啊不够200字! 在<JavaScript高级程序设计>中,分门别类介绍了非常多数组方法,其中迭代方法里面有6种,这6种方法在实际项目有着非常广泛的作 ...

  7. JavaScript中数组的迭代方法:forEach、map、filter、reduce、every、some、for in、for of

    JavaScript中有非常多数组迭代方法,这里基本上吧所有的都介绍全了,我项目中比较喜欢的是forEach. 7.for in (for-in循环实际是为循环对象而设计的,for in也可以循环数组 ...

  8. javascript中数组的map方法

    map方法原型:array1.map(callbackfn[, thisArg]) 参数: array1,必选. 一个数组对象.该函数一般用于数组对象 callbackfn,必选. 最多可以接受三个参 ...

  9. Javascript中数组重排序方法详解

    在数组中有两个可以用来直接排序的方法,分别是reverse()和sort().下面通过本文给大家详细介绍,对js 数组重排序相关知识感兴趣的朋友一起看看吧. 1.数组中已存在两个可直接用来重排序的方法 ...

随机推荐

  1. [转载]MATLAB中神经网络的函数

    1.设计函数 solvein    设计线性网络:                solverb   设计径向基网络:                      solverbe    设计精确的径向 ...

  2. 重磅 | 腾讯云服务网格开源项目 Aeraki Mesh 加入 CNCF 云原生全景图

    作者 赵化冰,腾讯云工程师,Aeraki Mesh 创始人,Istio member,Envoy contributor,目前负责 Tencent Cloud Mesh 研发工作. 摘要 近日,腾讯云 ...

  3. LGP5341题解

    SAM一道很裸的题... 题意很明确,不再阐述. 做法很简单:找到所有出现次数为 \(k\) 的子串,然后统计. 怎么找到这些字符串呢?SAM 只能找出等价类啊. 注意 parent tree 的父亲 ...

  4. TypeError: put() missing 1 required positional argument: 'item'问题分析

    今天博主在练习带参数线程池的时候与到了如下问题: 翻译过来,就是缺少位置参数. 一.错误1 如果此时你的代码高亮是这样: 解决办法:在init魔法方法下的Queue没有加括号,即 self.q = Q ...

  5. 使用systemd-analyze 工具来分析各个服务进程的启动性能

    systemd-analyze是一个分析启动性能的工具,用于分析启动时服务时间消耗.默认显示启动是内核和用户空间的消耗时间:使用systemd-analyze plot > boot.svg生成 ...

  6. 后门及持久化访问4----Com组件劫持

    代码及原理介绍 COM是Component Object Model(组件对象模型)的缩写,COM组件由DLL和EXE形式发布的可执行代码所组成.每个COM组件都有一个CLSID,这个CLSID是注册 ...

  7. Docker容器入门介绍

    1.前言 Docker是一种新兴的虚拟化技术,能够一定程度上的代替传统虚拟机.不过,Docker 跟传统的虚拟化方式相比具有众多的优势.Docker: 本意是码头工人,言外之意是集装箱: Java号称 ...

  8. Prometheus由于时间不同步导致数据不显示

    原文链接:Prometheus由于时间不同步导致数据不显示 问题 部署 prometheus 后,访问前端界面发现: 这是由于你windows机器与部署prometheus服务器的时间不同步导致的. ...

  9. Python 中 PyQt5 库语法(一)

    目录 PyQt5库(一) 一. 简介 1. 什么是 Qt 2. 什么是PyQt 3. 环境搭建 二. 基本结构 1. 第一个程序 2. 控件操作 3. 快速生成代码 4. 面向对象 三. 基类控件 1 ...

  10. 利用 ps 怎么显示所有的进程? 怎么利用 ps 查看指定进程的信息?

    ps -ef (system v 输出)ps -aux bsd 格式输出ps -ef | grep pid