• 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到这里。
    之前,没有写博客的习惯,只习惯把平时的总结放到有道云笔记中,没想到把观点写出来着实要花点心思的,因为要考虑如何表达,才能让别人更好地理解。

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

  • 相关阅读:
    Python3中最常用的5种线程锁你会用吗
    学会使用Python的threading模块、掌握并发编程基础
    数据结构与算法Python版 熟悉哈希表,了解Python字典底层实现
    博客导读
    分享canvas的一个小案例
    Php中的魔术方法
    进制简介
    Gojs学习史(一):基本定义
    Vue读书笔记:关于$ref、props和$emit
    Leaflet学习笔记(一)
  • 原文地址:https://www.cnblogs.com/langjt/p/4209771.html
Copyright © 2020-2023  润新知