美文网首页前端开发『巨坑』系列教程
前端开发『巨坑』系列—类数组详解

前端开发『巨坑』系列—类数组详解

作者: 党云龙 | 来源:发表于2019-12-21 23:11 被阅读0次

    这个数据好像不是数组


    当后台给我们传递了一个数组,我们正好来一个v-for美滋滋循环的时候。突然之间就报错了。
    循环不起来的我仔细查看得到的内容。是数组没错啊:

    data = {
        "0":1,
        "1":2,
        length:2,
        __proto__:Array.prototpye
    }
    

    等等,好像有什么地方不太对劲。我记得数组,好像是方括号啊,为什么它这个东西是花括号。

    最特么蛋疼的是,我使用Object.getPrototypeOf查看proto时,里面的内容显示这个数据确实是一个array。

    我们都知道,当使用console.log打印一个数组的时候,是可以看到,正常的数组中,包括内容,length,和proto三部分。

    重点就是这个proto,这里我们得复习一下原型链了,原型链就是指,你到底创见的是谁的实例,它包含的是实例的信息。比如说,我们new Array,创建的就是Array,它的proto就指Array。

    它是个身份信息。

    令人迷惑的地方也就在这里了,我打印这货的proto。它确实是一个数组。但是为什么它不能使用数组方法去循环了。

    调查之下,我发现了真相。

    这货只是一个看起来像数组的,伪数组。或者叫,类数组。

    并且它的proto还特么指向了Array.prototype,Array的原型链。所以,它从身份信息上看,确实是数组。但是,它的并不是通过new Array出来的。

    请接着看。

    如何判断一个数据是数组


    请先看例子:

    var arr = [1,2,3];
    //判断是否为数组
    console.log(Array.isArray(arr));
    
    //typeof只能用于检测基本类型 不能用于检测array
    console.log(typeof []); //object
    console.log(typeof {}); //object
    console.log(typeof function(){}); //function
    
    console.log(typeof "abc"); //string
    console.log(typeof 123); //number
    
    var a;//定义a但是不给a赋值
    console.log(typeof a); //undefined
    console.log(typeof null); //object 是的你没看错,null的数据类型就是object
    //https://blog.csdn.net/qq_36689178/article/details/81503605
    console.log(typeof undefined); //undefined
    

    可见检查变量类型的方法有两个,一个是typeof,另一个是更具有针对性的Array.isArray方法。

    typeof如果你检查的是一个引用类型,那么一定会返回object,比如说数组。所以这里你必须使用Array.isArray来判断。

    那么,我们如果不使用es6,在es5中有没有办法判断一个数据是array呢?当然能了!官方提供了一个Object.prototype.toString.call()方法。

    就算你伪装的很像也依然能判断出来!

    var a =[1,2,3]
    console.log(Object.prototype.toString.call(a)); //[object Array]
    var larr = {
        "0":1,
        "1":2,
        "length":2,
        __proto__:Array.prototype
    }
    console.log(Object.prototype.toString.call(larr)); //[object Object]
    

    在es6中提供了Array.isArray和Array.from方法,判断和转化数组,非常的方便。
    es6中类数组转化为数组和判断数组的方式。

    var larr = {
        "0":1,
        "1":2,
        "length":2,
        __proto__:Array.prototype
    }
    
    //es6
    //类数组
    console.log(Array.isArray(larr));//fales
    console.log(Array.isArray(Array.from(larr)));//ture
    

    如果你需要在es5中转化类数组 ,需要使用

    var a={length:2,0:'aaa',1:'bbb'};  
    Array.prototype.slice.call(a);//  ["aaa", "bbb"]   
      
    var a={length:2};  
    Array.prototype.slice.call(a);//  [undefined, undefined]  
    

    Object.prototype.toString.call详解


    toString这个方法非常好理解

    比如:

    var a = [1,2]
    console.log(a.toString());
    

    使用toString方法以后,变成1,2
    这个方法的意思是把对象里面的内容变成字符串。

    ok,那么Object.prototype就是指一个对象的prototype。

    call方法,用于改变this指针的方向。

    这里,最后括号里面放进去的是array本身,因为array对象本身也返回一个构造函数,通过call把构造函数本身的this指向obj,来调用Object.prototype.toString。

    相关文章

      网友评论

        本文标题:前端开发『巨坑』系列—类数组详解

        本文链接:https://www.haomeiwen.com/subject/kcunnctx.html