【前端基础系列】slice方法将类数组转换数组实现原理
2018-08-29 23:36
337 查看
问题描述
在日常编码中会遇到将类数组对象转换为数组的问题,其中常用到的一种方式使用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; }
由以上代码可以看出,当没有输入参数的时候,会创建一个新数组,然后把当前数组的所有元素扔进去,最后返回这个新数组。
参考
相关文章推荐
- 【前端基础系列】理解bind方法使用与实现
- JS基础篇--函数实际参数转换成数组的方法[].slice.call(arguments)
- .NET基础扩展系列-事件的实现原理
- php实现将数组转换为XML的方法
- byte数组转float实现与byte转换其它类型时进行&运算原理
- python实现将元祖转换成数组的方法
- Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用
- C语言基础系列--返回字符串函数的四种实现方法
- PHP数组与对象之间使用递归实现转换的方法
- php实现数组中索引关联数据转换成json对象的方法
- Haar特征原理与icvCreateIntHaarFeatures方法的具体实现附详细注释—— 人脸识别的尝试系列(二)
- 黑马程序员——Java基础 数组排序的两种实现方法,选择和冒泡
- 同余幂的原理和C++实现,附赠一个10进制数转换为任意进制的数组的算法。
- PHP数组与对象之间使用递归实现转换的方法
- python实现将元祖转换成数组的方法
- .NET基础扩展系列-事件的实现原理
- @V@ java代码笔记2010-06-12:java控制台输入各类型类实现;以及判断输入字符串里面是否有数字的两种方法:方法1:转换成字符数组;方法2:正则表达式。
- C#实现字符串转换成字节数组的简单实现方法
- PHP 数组和字符串互相转换实现方法
- rust 用指针类型转换的方法将u8数组(或slice)转换成u32