Array.prototype.slice.apply可以转换数组的原理

CodeAdventurer
• 阅读 5232

我们经常可以看到这种写法。

function test(){  
 //将参数转为一个数组  
 var args = Array.prototype.slice.apply(arguments);
  console.log(args)
} 

一般我们网上看到解释都是,对于js中的arguments来说,并不是一个真正的数组,可以叫它伪数组,通过Array.prototype.slice.apply方法,可以将其转化成数组,那让我们调用这个函数,看下函数中的参数数组。

test(11,22);  //[11,12]

同样的,我们可以先输出下函数内部的arguments。

console.log(arguments);     //[11,12,callee:,length:2]

可以看到,arguments确实不是一个纯数组。那么slice方法在将处理arguments并返回一个参数数组这个过程中,具体做了什么呢。让我们先了解下slice这个方法。
slice()方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象,且原始数组不会被修改。
语法

array.slice(begin,end);

参数
begin 可选,从该索引出开始提取原数组中的元素(从0开始)。如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。如果省略begin,则slice从索引0开始。
end 可选。从该索引处结束提取原数组元素(从0开始)。slice会提取原数组中索引从begin到end的所有元素(包含begin,但不包含end)。
slice(1,4)提取原数组中的第二个元素开始直到第四个元素的所有元素(索引为1,2,3的元素)。
如果该参数为负数,则表示在数组中的倒数第几个元素结束抽取。slice(-2,-1)表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)
另外:如果end被省略,则slice会一直提取到数组末尾。
如果end大于数组长度,slice也会一直提取到原数组末尾。
返回值
一个含有提取元素的新数组。
关于基本的slice的使用,我相信很容易理解也很容易使用。但是slice有两个特殊的地方.slice不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:
1、如果该元素是个对象引用(不是实际的对象),slice会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中这个元素也会发生改变。这个很好理解,看一个例子就明白。

var aa_aa = {x:1};
var aa_arr = [1,2,aa_aa];
aa_aa.x = 2;
console.log(aa_arr.slice(-1)); //[{x:2}]

2、对于字符串、数字及布尔值来说(不是String、Number或者Boolean对象),slice会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。这个也很容易理解,可参考我之前的文章,对引用类型和基本类型的介绍。
如果向两个数组任一个添加了新元素,则另一个不会受到影响。
以上内容来自MDN关于slice方法的介绍。
那现在我们知道,slice方法拥有将原数组中的元素浅复制到新数组中,并返回一个新数组的能力。那对于这里的函数。首先,利用apply方法让当前的函数内的arguments可以使用slice方法,然后slice方法将arguments中的11和12两个元素浅复制到新数组,并返回,这就实现了从arguments到数组的转变

function test(){  
 //将参数转为一个数组  
 var args = Array.prototype.slice.apply(arguments);
  console.log(args)
} 
test(11,12);

参考链接:
https://developer.mozilla.org...

点赞
收藏
评论区
推荐文章
翼
4年前
js 数组 转为树形结构
需要转换为树形的数组vardata{"orderById":null,"platformCommissionProportion":1,"name":"添加剂","pid":13,"id":26
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Easter79 Easter79
3年前
svg自适应写法
svg自适应写法<pre<!DOCTYPEhtml<htmllang"en"<head<metacharset"UTF8"<titleDocument</title</head<body<divstyle"width:30%;height:3.6rem;"<svg
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
菜园前端 菜园前端
2年前
什么是函数组合?
原文链接:什么是函数组合?函数组合(Compose),如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间过程的函数合并成一个函数。函数组合默认是从右到左执行,每个函数只能接收一个参数,否则需使用柯里化进行转换。作用函数组合可以让我们把细粒度的
Wesley13 Wesley13
3年前
Java开发者容易犯的十个错误
!(https://oscimg.oschina.net/oscnet/c9f00cc918684fbe8a865119d104090b.gif)Top1.数组转换为数组列表将数组转换为数组列表,开发者经常会这样做:\java\List<StringlistArrays.asList(arr);Arr
可莉 可莉
3年前
10 个很实用的 JavaScript 技巧
编程语言通常暗藏着各种技巧,熟练使用这些技巧可以提高开发效率。JavaScript就是一门技巧性很强的语言,掌握常见的语法技巧不但可以加深对语言特性的理解,还可以简化代码,提高编码效率。本文分享10个常用的技巧,希望能成为你的开发工具箱的一部分。1arguments对象转成数组arguments对象是函数内可访问的类数组对象,包含了传给函
Wesley13 Wesley13
3年前
ES6 扩展运算符 三点(...)
含义扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。console.log(...1,2,3)//123console.log(1,...2,3,4,5)//12345...
Stella981 Stella981
3年前
JSON.stringify()
JSON.stringify() 将一个JavaScript值(对象或者数组)转换为一个JSON字符串,如果指定了replacer是一个函数,则可以选择性的替换值,或者如果指定了replacer是一个数组,可选择性的仅包含数组指定的属性。语法:JSON.stringify(_value_,_replacer_,_sp