【前端基础系列】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;
}
由以上代码可以看出,当没有输入参数的时候,会创建一个新数组,然后把当前数组的所有元素扔进去,最后返回这个新数组。
参考
【前端基础系列】slice方法将类数组转换数组实现原理的更多相关文章
- JS数组 选定元素slice() slice() 方法可从已有的数组中返回选定的元素。 语法 arrayObject.slice(start,end)
选定元素slice() slice() 方法可从已有的数组中返回选定的元素. 语法 arrayObject.slice(start,end) 参数说明: 1.返回一个新的数组,包含从 start 到 ...
- JS基础篇--sort()方法的用法,参数以及排序原理
JS基础篇--sort()方法的用法,参数以及排序原理 sort() 方法用于对数组的元素进行排序,并返回数组.默认排序顺序是根据字符串Unicode码点.语法:arrayObject.sort( ...
- 快学Scala 第三课 (定长数组,变长数组, 数组循环, 数组转换, 数组常用操作)
定长数组定义: val ar = new Array[Int](10) val arr = Array("aa", "bb") 定长数组赋值: arr(0) = ...
- 【前端基础系列】理解bind方法使用与实现
方法描述 bind()方法创建一个新函数,当被调用时,将其this关键字设置为提供的值. 语法说明 fn.bind(thisArg,arg1,arg2,..) 参数说明 thisArg:当绑定函数被调 ...
- js作用域与执行环境(前端基础系列)
一.作用域(what?) 官方解释是:"一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域." 单从文字理解比较难懂,举个栗子: ...
- javascript 命名空间与运用(前端基础系列)
所谓代码,当你随便命名一个变量:var name = "ukerxi"; 就是一句代码:但当你的代码写出来后,对于后续维护及阅读的人,就可以看出代码是否,易读,易理解:优雅的代码总 ...
- “use strict” 严格模式使用(前端基础系列)
ECMAscript5添加一种严格模式的运行模式("use strict"),让你的js语句在更加严格的环境下进行运行: 一.主要作用: 消除版本javascript中一些不合理及 ...
- openlayers3 基础(常见方法,类及实现)
ol3接口大全1.ol.Map类:(地图容器类) 实现: ol.Map(参数) 参数说明:1.1 target,说明地图所在的html元素. 如果没有指定,必须调用ol.Map类的setTarget( ...
- java基础37 集合框架工具类Collections和数组操作工具类Arrays
一.集合框架工具类:Collections 1.1.Collections类的特点 该工具类中所有的方法都是静态的 1.2.Collections类的常用方法 binarySearch(List< ...
随机推荐
- 解决Windows 10笔记本接显示器分屏后没有声音的问题
Windows 10 版本号:17763.292 1.首先右键点击任务栏托盘中的[扬声器]图标,选择[声音],如下图所示. 2.选择[播放],然后选择[扬声器],再点击[设为默认值],如下所示. 3. ...
- SIFT+BOW 实现图像检索
原文地址:https://blog.csdn.net/silence2015/article/details/77374910 本文概述 图像检索是图像研究领域中一个重要的话题,广泛应用于医学,电子商 ...
- 通过python生成nginx模板配置文件
通过python生成nginx模板配置文件 # cat config.py #coding=utf-8 nginx_conf = ''' server {{ listen {port}; server ...
- 【原创】Linux基础之Shell脚本常用命令
#!/bin/sh 1 取脚本参数 $# 参数个数$0 当前脚本名$1 第1个参数$n 第n个参数$* 所有参数$@ 所有参数$? 上个命令的状态$$ 当前pid 2 日期 $ dateWed Mar ...
- [POSIX]文件系统(概述)
1.文件名由除系统目录分隔符(unix是/,windows是\)和空字符“\0”外的任意ASCII字符组成,现代系统很多还可以包含UNICODE字符,但是还是推荐使用传统的ASCII码命名. 2.目录 ...
- SqlBulkCopy 之 Received an invalid column length from the bcp client for colid 5.
SqlBulkCopy 批量复制报错: Received an invalid column length from the bcp client for colid 5. 翻译:从bcp客户端收到一 ...
- linux显示完整目录
vim ~/.bashrc ##添加以下信息 export PS1='[\u@\h `pwd`]$ ' 然后保存退出 source ~/.bashrc 或者关机重新启动即可
- 3、SourceTree通过PUTTY连接GitLab
一.生成公钥和私钥 使用命令行生成(两种生成方式选择一种即可) 1.安装SourceTree打开SourceTree,点击“命令行模式”. 2.输入如下命令生成key“example@example. ...
- windows+mysql集群搭建-三分钟搞定集群
注:本文来源: 陈晓婵 < windows+mysql集群搭建-三分钟搞定集群 > 一:mysql集群搭建教程-基础篇 计算机一级考试系统要用集群,目标是把集群搭建起来,保证一 ...
- 小学生都看得懂的C语言入门(5): 指针
现在已经学到C语言的后面了, 快学完咯.... (一)取地址运算 先来看一下sizeof 计算所占字节 #include<stdio.h> int main() { int a; a=; ...