• 在JavaScript中,如何判断数组是数组?


    产生问题原因 用typeof运算符来判断不足地方

    typeof是javascript原生提供的判断数据类型的运算符,它会返回一个表示参数的数据类型的字符串,例如:

    以下是在MDN的文档中找到的一张包含typeof运算法的针对不同类型的输出结果:

    console.log(typeof 2);               // number
    console.log(typeof true);            // boolean
    console.log(typeof 'str');           // string
    console.log(typeof []);              // object     []数组的数据类型在 typeof 中被解释为 object
    console.log(typeof function(){});    // function
    console.log(typeof {});              // object
    console.log(typeof undefined);       // undefined
    console.log(typeof null);            // object     null 的数据类型被 typeof 解释为 object

    空数组 和 null被 typeof 解释为 object 类型,有的人可能会认为 typeof 关键字对数组 和 null 的类型判断是错误的,其实typeof对于数组 和 null 的类型判断是正确的,只不过不够精准而已。

    在参数为数组,对象或者null时,typeof返回的结果都是object,可以使用这种方法并不能识别出数组,

    因此,在JavaScript项目中用typeof来判断一个位置类型的数据是否为数组,是非常不靠谱的。

    用Object的toString方法判断

    另一个行之有效的方法就是使用Object.prototype.toString方法来判断,每一个继承自Object的对象都拥有toString的方法。

    如果一个对象的toString方法没有被重写过的话,那么toString方法将会返回"[object type]",其中的type代表的是对象的类型,根据type的值,我们就可以判断这个疑似数组的对象到底是不是数组了。

    你可能会纠结,为什么不是直接调用数组,或则字符串自己的的toString方法呢?我们试一试就知道了。

    const a = ['Hello','Howard'];
    const b = {0:'Hello',1:'Howard'};
    const c = 'Hello Howard';
    a.toString();//"Hello,Howard"
    b.toString();//"[object Object]"
    c.toString();//"Hello,Howard"

    从上面的代码可以看出,除了对象之外,其他的数据类型的toString返回的都是内容的字符创,只有对象的toString方法会返回对象的类型。所以要判断除了对象之外的数据的数据类型,我们需要“借用”对象的toString方法,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。

    const a = ['Hello','Howard'];
    const b = {0:'Hello',1:'Howard'};
    const c = 'Hello Howard';
    Object.prototype.toString.call(a);//"[object Array]"
    Object.prototype.toString.call(b);//"[object Object]"
    Object.prototype.toString.call(c);//"[object String]"

    使用apply方法也能达到同样的效果:

    const a = ['Hello','Howard'];
    const b = {0:'Hello',1:'Howard'};
    const c = 'Hello Howard';
    Object.prototype.toString.apply(a);//"[object Array]"
    Object.prototype.toString.apply(b);//"[object Object]"
    Object.prototype.toString.apply(c);//"[object String]"

    如下是我测试所有数据类型结果  都是可以的

    总结一下,我们就可以用写一个方法来判断数组是否为数组:

    1、判断数组函数:

    const isArray = (something)=>{
        return Object.prototype.toString.call(something) === '[object Array]';
    }

    但是,如果你非要在创建这个方法之前这么来一下,改变了Object原型链上的toString方法,那我真心帮不了你了...

    //重写了toString方法
    Object.prototype.toString = () => {
        alert('你吃过了么?');
    }
    //调用String方法
    const a = [];
    Object.prototype.toString.call(a);//弹框问你吃过饭没有

    2、JavaScript Array isArray() 方法

    定义和用法

    isArray() 方法用于判断一个对象是否为数组。

    如果对象是数组返回 true,否则返回 false。


    浏览器支持

    表格中的数字表示支持该方法的第一个浏览器版本号。

    方法          
    isArray() 5 9.0 4 5 10.5

    语法

    Array.isArray(obj)

    参数

    参数 描述
    obj 必需,要判断的对象。

    技术细节

    返回值: 布尔值,如果对象是数组返回 true,否则返回 false。
    JavaScript 版本: ECMAScript 5

    它是我目前遇到过的最靠谱的判断数组的方法了,当参数为数组的时候,isArray方法返回true,当参数不为数组的时候,isArray方法返回false。

    const a = [];
    const b = {};
    Array.isArray(a);//true
    Array.isArray(b);//false
    let a = Array.isArray(1);
    let b = Array.isArray({});
    let c = Array.isArray("");
    let d = Array.isArray(null);
    let e = Array.isArray(true);
    let f = Array.isArray(undefined);
    console.log(a,b,c,d,e,f);
    
    let a = Array.isArray(1);
    let b = Array.isArray({});
    let c = Array.isArray("");
    let d = Array.isArray(null);
    let e = Array.isArray(true);
    let f = Array.isArray(undefined);
    console.log(a,b,c,d,e,f);

    我试着在调用这个方法之前重写了Object.prototype.toString方法:

    Object.prototype.toString = ()=>{
        console.log('Hello Howard');
    }
    const a = [];
    Array.isArray(a);//true

    并不影响判断的结果。

    我又试着修改了constructor对象:

    const a = [];
    const b = {};
    a.constructor = b.constructor;
    Array.isArray(a);//true

    OK,还是不影响判断的结果。

    可见,它与instance运算符判断的方法以及Object.prototype.toString法并不相同,一些列的修改并没有影响到判断的结果。

    你可以放心大胆的使用Array.isArray去判断一个对象是不是数组。
    除非你不小心重写了Array.isArray方法本身。。

    ,Array.isArray是ES5标准中增加的方法,部分比较老的浏览器可能会有兼容问题,所以为了增强健壮性,建议还是给Array.isArray方法进行判断,增强兼容性,重新封装的方法如下:

    if (!Array.isArray) {
      Array.isArray = function(arg) {
        return Object.prototype.toString.call(arg) === '[object Array]';
      };
    }
  • 相关阅读:
    虚拟机vmware下安装Ghost XP——正确的解决方案
    spring结合quartz的定时的2种方式
    Spring ClassPathXmlApplicationContext和FileSystemXmlApplicationContext
    Spring--Quartz 任务调度的配置详解
    Redis并发问题
    Eclipse默认标签TODO,XXX,FIXME和自定义标签
    使用storyboard创建带有navigation的界面的简单方法
    Java高级之线程同步
    XCode中的单元测试:编写测试类和方法(内容意译自苹果官方文档)
    MapReduce 应用:TF-IDF 分布式实现
  • 原文地址:https://www.cnblogs.com/ddqyc/p/16206166.html
Copyright © 2020-2023  润新知