zoukankan      html  css  js  c++  java
  • 【前端基础系列】slice方法将类数组转换数组实现原理

    问题描述

    在日常编码中会遇到将类数组对象转换为数组的问题,其中常用到的一种方式使用Array.prototype.slice()方法。

    类数组对象

    所谓的类数组对象,JavaScript对它们定义为:它们看起来很像数组,只是具有部分和数组相同特性:

    • 拥有length属性
    • 元素保存在对象中,可以通过索引访问
      但是没有数组的其他方法,例如:push、slice、indexOf等。

    转换过程

    例如:

    var foo = {
        0: 'Java',
        1: 'Python',
        2: 'JavaScript',
        length: 3
    };
    // 因为foo对象本身并没有slice方法,所以通过call调用
    var arr = Array.prototype.slice.call(foo); // [‘Java’,’Python’,’JavaScript’]
    

    那么问题来了,为什么slice方法可以将对象转换为数组?最简单的方式就是查看源码实现。

    源码实现

    可以查看V8引擎中的Array内部方法实现

    function ArraySlice(start, end) { 
    
    CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); 
    var array = TO_OBJECT(this); 
    var len = TO_LENGTH(array.length); 
    var start_i = TO_INTEGER(start); 
    var end_i = len; 
    if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); 
    if (start_i < 0) { 
    start_i += len; 
    if (start_i < 0) start_i = 0; 
    } else { 
    if (start_i > len) start_i = len; 
    } 
    if (end_i < 0) { 
    end_i += len; 
    if (end_i < 0) end_i = 0; 
    } else { 
    if (end_i > len) end_i = len; 
    } 
    var result = ArraySpeciesCreate(array, MaxSimple(end_i - start_i, 0)); // 先转换为数组
    if (end_i < start_i) return result; // 如果没有任何参数,直接返回数组
    if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) { 
    %NormalizeElements(array); 
    if (IS_ARRAY(result)) %NormalizeElements(result); 
    SparseSlice(array, start_i, end_i - start_i, len, result); 
    } else { 
    SimpleSlice(array, start_i, end_i - start_i, len, result); 
    } 
    result.length = end_i - start_i; 
    return result; 
    } 
    

    由以上代码可以看出,当没有输入参数的时候,会创建一个新数组,然后把当前数组的所有元素扔进去,最后返回这个新数组。

    参考

    V8的array实现

  • 相关阅读:
    SpringMVC注解控制器详解
    在自己的服务器上安装GitBook
    基于UDP协议的网络编程
    RabbitMQ安装使用详解
    Python3.4 + Django1.7.7 搭建简单的表单并提交
    暴力枚举 UVA 10976 Fractions Again?!
    暴力枚举 UVA 725 Division
    思维 UVALive 3708 Graveyard
    DFS(剪枝) POJ 1011 Sticks
    DFS+模拟 ZOJ 3861 Valid Pattern Lock
  • 原文地址:https://www.cnblogs.com/GeniusLyzh/p/9557697.html
Copyright © 2011-2022 走看看