zoukankan      html  css  js  c++  java
  • js 数组和类数组的区别

    类数组定义

      1)拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理);
          2)不具有数组所具有的方法;

      javascript中常见的类数组有 arguments对象和 DOM方法的返回结果。比如 document.getElementsByTagName()

      判断是否是类数组

      

    1
    2
    3
    4
    5
    6
    7
    8
    function isLikeArray(o) {
        if (typeof o === 'object' && isFinite(o.length) &&  o.length >= 0 && o.length < 4294967296){
            // 4294967296: 2^32
            return true
        } else {
            return false
        }
    }


    类数组转换为数组

    args = Array.prototype.slice.call(arguments);

    // 类数组转换为数组首先Array.prototype.slice.call(arrayLike)的结果是将arrayLike对象转换成一个Array对象。所以其后面可以直接调用数组具有的方法

    Array.prototype.slice

      slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。

    String 对象的方法 slice()、substring() 和 substr() (不建议使用)都可返回字符串的指定部分。slice() 比 substring() 要灵活一些,因为它允许使用负数作为参数。slice() 与 substr() 有所不同,因为它用两个字符的位置来指定子串,而 substr() 则用字符位置和长度来指定子串。

    还要注意的是,String.slice() 与 Array.slice() 相似。

    Array.slice

    返回值

    返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。

    说明

    请注意,该方法并不会修改数组,而是返回一个子数组。如果想删除数组中的一段元素,应该使用方法 Array.splice()。

    (1)Array.prototype.slice表示数组的原型中的slice方法。注意这个slice方法返回的是一个Array类型的对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //slice的内部实现
    Array.prototype.slice = function(start,end){ 
          var result = new Array(); 
          start = start || 0; 
          end = end || this.length; //this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键 
          for(var i = start; i < end; i++){ 
               result.push(this[i]); 
          
          return result; 
     }

      

    (2)能调用call的只有方法,所以不能用[].call这种形式,得用[].slice。而call的第一个参数表示真正调用slice的环境变为了arrayLike对象。所以就好像arrayLike也具有了数组的方法。

    (3)附上转成数组的通用函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var toArray = function(s){ 
        try
            return Array.prototype.slice.call(s); 
        } catch(e){ 
                var arr = []; 
                for(var i = 0,len = s.length; i < len; i++){ 
                    //arr.push(s[i]); 
                     arr[i] = s[i];     //据说这样比push快
                
                 return arr; 
        }

      

    //也可以用es6

    Array.from方法转为数组
    如果有不支持
    Array.from方法的浏览器,可以用Array.prototype.slice方法替代
    const toArray = (() => 
        Array.from ? Array.from : obj => [].slice.call(obj)
    )();

    Array.from使用


    Array.from('一二三四五六七') // ["一", "二", "三", "四", "五", "六", "七"] // 等效的es5是'一二三四五六七'.split('')
    Array.from(new Set([1,2,1,2])) // 等效[...new Set([1,2,1,2])] => [1,2] // 用来数组去重
    Array.from(new Map([[1, 2], [2, 4], [4, 8]])) // 接受一个map
    Array.from(arguments)
    // 接受一个类数组对象
    Array.from(document.querySelectorAll('div')) Array.from({1: 2,length:3}) // [undefined, 2, undefined]

      类数组和数组的区别 

    ① instanceof

    ② constructor

    ③ toString()

    ④ ES 提供的方法 isArray()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <ul id="list">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
        </ul>
        <script type="text/javascript">
        // 获取所有li
        var lis = document.getElementsByTagName("li");
        // 定义数组
        var arr = [];
        // 请问有几种方式来区别类数组和数组?
         
        // typeof 用来判断类型 (是值类型还是引用类型) 返回的是一个字符串
      
        // 第一种方式 instanceof
        console.log(arr instanceof Array);
        console.log(lis instanceof Array);
      
        // 第二种方式
        console.log(arr.constructor === Array)
        console.log(lis.constructor === Array)
      
        // 第三种方式
        console.log(Object.prototype.toString.call(arr) === "[object Array]")
        console.log(Object.prototype.toString.call(lis) === "[object Array]")
      
        // 使用ES5提供的方法
        console.log(Array.isArray(arr))
        console.log(Array.isArray(lis))
        </script>
    </body>
    </html>

      将数组转化为类数组(参数列表)

    调用apply方法的时候,第一个参数是对象(this), 第二个参数是一个数组集合,   这里就说明apply的一个巧妙用法,可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3), 这个如果让我们用程序来实现将数组的每一个项,来转换为参数的列表,可能都得费一会功夫,借助apply的这点特性,所以就有了以下高效率的方法。

    可以看看  js函数中的apply()、call()、bind()方法 ---(apply的其他巧妙用法(一般在什么情况下可以使用apply))

      (1)Math.max 实现得到数组中最大的一项  

    因为Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组 ,但是它支持Math.max(param1,param2,param3…),所以

    可以根据刚才apply的那个特点来解决 var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项  (apply会将一个数组装换为一个参数接一个参数的传递给方法)  

     这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null。

    1
    2
    var arr = new Array(1,2,3,4,5);
    var max = Math.max.apply(null,arr);    //5

      

    (2)Array.prototype.push 可以实现两个数组合并

      同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN);

      如果我们要把 arr2展开,然后一个一个追加到arr1中去,最后让arr1=[“1”,“2”,“3”,“4”,“5”,“6”]
      arr1.push(arr2)显然是不行的,因为这样做会得到[“1”,“2”,“3”,[“4”,“5”,“6”]]

      我们只能用一个循环去一个一个的push(当然也可以用arr1.concat(arr2),但是concat方法并不改变arr1本身,需要重新定义一个变量)

      所以同样也可以通过apply来转换一下这个数组,即: 

    1
    2
    3
    4
    var arr1=new Array("1","2","3");  
    var arr2=new Array("4","5","6");  
    Array.prototype.push.apply(arr1,arr2);<br>  console.log(arr1,arr2)
    console.log("arr1="+arr1+",arr2="+arr2);
    1
     

       也可以理解arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合.。

    文章来源:https://www.cnblogs.com/jiayeyuan/p/10886568.html

  • 相关阅读:
    命令行工具--netstat
    Man手册--nmap
    bc -l 对于 %取模计算出错
    离散对数和原根 欧拉定理证明
    bc-win32-power-echo-vim-not-work
    2010版EXCEL下方sheet工作表隐藏了
    word多出空标题,样式是列出段落
    plantuml
    久石让《龙猫》豆豆龙 钢琴视奏版
    神奇校车 = topsage
  • 原文地址:https://www.cnblogs.com/ruishuiweixiang/p/13572255.html
Copyright © 2011-2022 走看看