zoukankan      html  css  js  c++  java
  • Javascript数组方法探究一二

    1. Array.prototype.slice方法
    数组的 slice 方法通常用来从一个数组中抽取片断。不过,它还有将“类数组”(比如arguments和​HTMLCollection​)转换为真正数组的本领。
    1 var nodesArr = Array.prototype.slice.call(document.forms);
    2 
    3 var argsArr = Array.prototype.slice.call(arguments);

    我就好奇了为什么数组的slice方法有这样的本领,它在javascript引擎中是如何实现的?slice的兄弟方法有没有这样的本领?

    带着好奇心,下载Google的V8 javascript引擎源码到本地,V8源码的下载地址:https://github.com/v8/v8。

    在v8-master/src/array.js中查找“Array.prototype.slice”:

     1 function ArraySlice(start, end) {
     2   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
     3   ...
     4   var result = []; // 这句是关键
     5 
     6   if (end_i < start_i) return result;
     7 
     8   if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
     9      ...
    10     SparseSlice(array, start_i, end_i - start_i, len, result);
    11   } else {
    12     SimpleSlice(array, start_i, end_i - start_i, len, result);
    13   }
    14   ...
    15   return result;

    接着猜想调用“类数组”走的应该是SimpleSlice方法,然后在源码查找“SimpleSlice“,发现Array.prototype.splice源码中也调用了SimpleSlice方法,且结果变量也初始化为空数组。不过,想用splice方法把“类数组”转化为真正数组,必须要传入起始位置参数为0,即:

     var nodesArr = Array.prototype.splice.call(document.forms, 0);

    因为它的实现原理就是将被删除的数组项组成新数组。感兴趣的童鞋可以看下Array.prototype.splice的源码实现。
    此外,slice还可以克隆一个数组:

    1 var arr = [1, 2, 3];
    2 var cloneArr = arr.slice(); // cloneArr:  [1, 2, 3]
    补充:
    使用以下方法也可将类数组转换为真实数组:
    (1). [].concat.apply([], 类数组); 
    (2). var arr = [];   [].push.apply(arr, 类数组);

    2. Array.prototype.push 方法
    使用 push方法可以合并数组:

    1 var arr1 = [1, 'str', {name: 'lang'}];
    2 var arr2 = [2, 'ing'];
    3 Array.prototype.push.apply(arr1, arr2);
    4 // 返回结果:[1, "str", {name: 'lang'}, 2, "ing"]

    3. Array.prototype.sort 方法
    先上代码:

    var arr = ['1', '2', '10', '12'];
    arr.sort();
    // 返回结果:["1", "10", "12", "2"]

    上面的结果通常不是我们想要的,那么如何按数值大小排序:

    arr.sort(function(a, b) {
      return a - b;
    })
    // 返回结果:["1", "2", "10", "12"]

    有了排序比较器函数之后,就可以自定义很多比较器,从而实现个性化的排序。

    4. length 属性
    数组的length属性,不是只读的,也就说还可写哦,比如使用length属性去截断数组:

    1 var arr = [1, 2, 3, 4];
    2 arr.length = 2;
    3 // arr: [1, 2]
    4 arr.length = 0;
    5 // arr: []

    与此同时,如果把length属性变大,数组的长度值变会增加,且使用undefined来作为新的元素填充。

    1 var arr = [];
    2 arr.length = 3;
    3 // arr: [undefined, undefined, undefined]

     

    好了,今天就总结到这里了,已经凌晨了,以后有什么新发现再append到这里。
    之前,没有写博客的习惯,只习惯把平时的总结放到有道云笔记中,没想到把观点写出来着实要花点心思的,因为要考虑如何表达,才能让别人更好地理解。

    有什么表达不对或理解错误的地方,还望大家帮忙指正出来。

  • 相关阅读:
    Jzoj4822 完美标号
    Jzoj4822 完美标号
    Jzoj4792 整除
    Jzoj4792 整除
    Educational Codeforces Round 79 A. New Year Garland
    Good Bye 2019 C. Make Good
    ?Good Bye 2019 B. Interesting Subarray
    Good Bye 2019 A. Card Game
    力扣算法题—088扰乱字符串【二叉树】
    力扣算法题—086分隔链表
  • 原文地址:https://www.cnblogs.com/langjt/p/4209771.html
Copyright © 2011-2022 走看看