解析Array.prototype.slice.call(arguments)
在es5标准中,我们经常需要把arguments对象转换成真正的数组
// 你可以这样写
var arr = Array.prototype.slice.call(arguments) // 你还可以这样写
var arr = [].slice.call(arguments) // 你要是不怕麻烦,你还可以这样写
var arr = [].__proto__.slice.call(arguments)
以上三种写法是等价的。
// 当你了解原型链,你就知道
Array.prototype === [].__proto__ // true // [].slice调用的是实例[]的原型对象中的slice方法
[].slice === [].__proto__.slice // true
Array.prototype.slice.call(arguments)原本调用slice的是Array.prototype,而call(arguments)使得调用slice方法的对象改成arguments,你可以想象成
Array.prototype.slice.call(arguments) ~ arguments.slice()
Array.prototype.slice.call(arguments, [begin[, end]]) ~ arguments.slice([begin [, end]])
我们可能会想arguments原型对象是Object.prototype,并没有slice方法,slice方法从哪里来?
这是因为call(arguments)不仅是改变了this的指向,还使得arguments对象继承了Array.prototype中的slice方法。
下面是Array.prototype.slice()源码:指路github地址 587行
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;
}
arguments可以转换为数组对象也是因为
我们可以看到arguments对象成员属性类似数组,且有length属性,那是不是这样类似的对象都可以调用slice呢,我们试验一下
var obj = {
0: 'foo',
1: 'bar',
2: 'arg',
length: 3
}
console.log(Array.prototype.slice.call(obj))
// ["foo", "bar", "arg"]
这是可以的!
*PS:es6语法中新增了Array.from(),所以上述类型的对象可以Array.from(obj)就直接转化成数组!
解析Array.prototype.slice.call(arguments)的更多相关文章
- 解析 Array.prototype.slice.call(arguments,0)
Array.prototype.slice.call(arguments,0) 经常会看到这段代码用来处理函数的参数 网上很多复制粘帖说:Array.prototype.slice.call(argu ...
- 观V8源码中的array.js,解析 Array.prototype.slice为什么能将类数组对象转为真正的数组?
在官方的解释中,如[mdn] The slice() method returns a shallow copy of a portion of an array into a new array o ...
- Array.prototype.slice.call(arguments)
Array.prototype.slice.call(arguments)能够将具有length属性的对象转化为数组, 可以理解为将arguments转化成一个数组对象,让它具有slice方法 如: ...
- 详解 Array.prototype.slice.call(arguments)
首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组 在这里我们看第二个方法 1.在JS里Array是一个类 slice是 ...
- Array.prototype.slice.call(arguments) 类数组转成真正的数组
Array.prototype.slice.call(arguments) 我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数 ...
- 转对象(含length属性)成数组Array.prototype.slice.call(arguments)
我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js ...
- js基础进阶--关于Array.prototype.slice.call(arguments) 的思考
欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...
- 理解Array.prototype.slice.call(arguments)
在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理: 1.基本讲解 1.在 ...
- Array.prototype.push.apply(a,b)和Array.prototype.slice.call(arguments)
Array.prototype.push.apply(a,b) 时常看到在操作数组的时候有这样的写法: var a = [1,2,3]; var b = [4,5,6]; a.push.apply(a ...
随机推荐
- Linux下svn的安装与部署
最近工作碰到一个问题,我和一个同伙负责开发一个管理系统,基于原来的代码上进行修改,每当他修改之后,我要再修改都要和他确定是不是最新的文件,才能进行修改.非常影响工作的效率,所以在网上找了关于svn的使 ...
- 在Maven仓库中添加Oracle数据库的JDBC驱动依赖
在使用idea连接oracle数据库时发现直接添加oracle依赖 <dependency><groupId>com.oracle</groupId><art ...
- JavaScript 常见面试题
此文内容多为 JavaScript 对数组理解及运用. 1.如何消除一个数组里面重复的元素? var arr = [1, 2, 3, 3, 4, 4, 5, 5, 6, 1]; var newArr ...
- github上手实践教程
简介: SSH公私钥的使用 github的使用 git 工具的基本使用 基本步骤: 一.github的使用 1.github账号的创建[官网一步一步创建就行了,这一步骤省略] 2.创建远程仓库: 创建 ...
- Windows access Linux / Ubuntu via Remote Desktop via xrdp
Windows 多用户远程桌面连接到 Ubuntu / Linux Access Ubuntu from Windows remotely Follow these steps : Step 1 ...
- Linux sar命令工具详细介绍
sar命令工具详细介绍 by:授客 QQ:1033553122 由于篇幅限制,采用网盘分享, 下载地址: sar命令工具详细介绍.pdf
- 132.1.001 Union-Find | 并查集
@(132 - ACM | 算法) Algorithm | Coursera - by Robert Sedgewick > Tip: Focus on WHAT is really impor ...
- stm32f103各个型号芯片之间程序移植(stm32的兼容问题)
1.stm32f103系列的各个型号的芯片差别一般不大,都是一些flash大小不一样,一般是向下兼容(大容量芯片兼容中容量芯片)还有晶振大小不一样. ...
- redis介绍(1)命令介绍
redis 的五大基本类型的简单命令 对key--value中的value的一些简单命令 keys * 查询redis中的所有key exists key 查询key是否存在 flushdb 清空当前 ...
- 删除maven本地库中下载不完全的jar包
@echo off rem 这里写你的仓库路径 set REPOSITORY_PATH= '本地仓库路径' rem 正在搜索... for /f "delims=" %%i in ...