在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)的更多相关文章

  1. 解析 Array.prototype.slice.call(arguments,0)

    Array.prototype.slice.call(arguments,0) 经常会看到这段代码用来处理函数的参数 网上很多复制粘帖说:Array.prototype.slice.call(argu ...

  2. 观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 ...

  3. Array.prototype.slice.call(arguments)

    Array.prototype.slice.call(arguments)能够将具有length属性的对象转化为数组, 可以理解为将arguments转化成一个数组对象,让它具有slice方法 如: ...

  4. 详解 Array.prototype.slice.call(arguments)

    首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组 在这里我们看第二个方法 1.在JS里Array是一个类 slice是 ...

  5. Array.prototype.slice.call(arguments) 类数组转成真正的数组

    Array.prototype.slice.call(arguments)   我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数 ...

  6. 转对象(含length属性)成数组Array.prototype.slice.call(arguments)

    我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js ...

  7. js基础进阶--关于Array.prototype.slice.call(arguments) 的思考

    欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...

  8. 理解Array.prototype.slice.call(arguments)

    在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理: 1.基本讲解 1.在 ...

  9. 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 ...

随机推荐

  1. python数据类型之字典

    字典定义 字典是一种 key-value 的数据类型,这点很重要,是区别使用列表和字典的依据. 语法格式: info = { 'stu1101': "Aaron", 'stu110 ...

  2. fontforge制作自定义字体及在手机上应用举例——张鑫旭

    一.看似无关紧要的事件背景 之所以花时间折腾fontforge这个软件,去制作什么自定义的字体是有原因滴. 之前提过,最近我抽空将公司的手机软件HTML5网页化.期间碰到这么一个问题,页面低栏上的电话 ...

  3. c#如何仅在datatgirdview控件的头部(列名处)添加右键菜单

    近期在弄ArcgisAE实习,其中有一个功能是需要操作图层的属性字段的,为了方便操作图层的属性,最好是在图层的属性表中,也就是在显示图层属性的DataGirdView控件的头部添加一个右键菜单来实现相 ...

  4. SQL SERVER DATETIME应用

    ),, , ),); ),, ),); ),, , ),); ),, ),); ),, , ),); ),, ),); How to get first and last day of previou ...

  5. iTem2 保持连接,解决ssh的"Write failed: Broken pipe"问题

    方法一: profiles -> sessions -> When idel, send ASCII code 问题场景 服务器环境:阿里云 Linux CentOS 主机 客户端:Mac ...

  6. Modernizing Business Process with Cloud and AI

    The world is awash with digital transformation. Every customer and partner that I talk to, across ev ...

  7. 【node】node的核心模块---http模块,http的服务器和客户端

    nodejs事件机制 ##### http服务器和客户端 node.js标准库提供了http模块,其中封装了一个高效的http服务器和一个简易的http客户端 HTTP服务器 1. http.crea ...

  8. linux 文件搜索命令find、-name、-iname、通配符*?、-size、-user、-group、-amin、-cmin、-mmin、-a、-o、-exec/-ok、-inum

    尽可能规划好目录结构,少用文件搜索操作,因为它会占用大量的系统资源 find /bin/find find [搜索范围] [匹配条件] find /etc -name initfind /etc -n ...

  9. 初次使用git就遭遇不测,提示没有这个服务连接和需要配置git的一个http参数 NO network connection,SSl host could not be verified ...

    第一次使用git 拉取服务上的项目到本地,结果,在拿到访问的url地址后,输入用户名密码,失败了. --eclispe  4.5.3 继承了git客户端插件的版本 ------下一步后,报错 NO n ...

  10. apache ftp server的简单入门(properties验证)

    Apache FTPServer:(开源) Apache FTPServer是一个100%纯Java的FTP服务器. 它的设计是基于现有的开放式协议的完整和便携式FTP服务器引擎解决方案.FTPSer ...