将函数里的arguments
,转换成一个真正的数组的方法。
arguments
是个类数组,除了有实参所组成的类似数组以外,还有自己的属性,如callee
,arguments.callee
就是当前正在执行的这个函数的引用,它只在函数执行时才存在。因为在函数开始执行时,才会自动创建第一个变量arguments
对象。
一、arguments
是个类数组
-
它将实参以数组的形式保存着,还可以像数组一样访问实参,如:
arguments[0]
; -
它也有自己独特的属性,如:
callee
; -
它的长度是实参的个数。
那
arguments.callee.length
又是什么呢?arguments.callee
是当前正在执行的函数的引用,类似function.length
,那就是形参的个数。
二、将arguments
转换为真正的数组的方法
1. Array.prototype.slice.apply(arguments)
这是运行效率比较快的方法(看别人资料说的),为什么不是数组也可以,因为arguments
对象有length
属性,而这个方法会根据length
属性,返回一个具有length
长度的数组。若length
属性不为number
,则数组长度返回0
;
所以其他对象只要有length
属性也是可以的哟,如对象中有属性0
,对应的就是arr[0]
,即属性为自然数的number
就是对应的数组的下标,若该值大于长度,当然要割舍啦。
2. Array.prototype.concat.apply(thisArg,arguments)
thisArg
是新的空数组,apply
方法将函数this
指向thisArg
,arguments
做为类数组传参给apply
。
根据apply
的方法的作用,即将Array.prototype.slice
方法在指定的this
为thisArg
内调用,并将参数传给它。用此方法注意:若数组内有数组,会被拼接成一个数组。原因是apply
传参的特性。
3. 我自己想了个方法,利用Array
的构造函数
如Array(1,2,3,4,5,6)
,可以返回一个传入的参数的数组。那Array.apply(thisArg,arguments)
也可以将arguments
转化为数组,果然实验是可以的。
有没有什么影响呢,就是乱用了构造函数,但这也是 JS 的特性嘛,构造函数也是函数。
用此方法注意:若数组内有数组,会被拼接成一个数组。
原因是apply
传参的特性。
4. 用循环
因为arguments
类似数组可以使用arguments[0]
来访问实参,那么将每项赋值给新的数组每项,直接复制比push
要快,若实参有函数或者对象,就要深拷贝。
三、综上所述
最完美的方法应该是Array.prototype.slice.apply(arguments)
了。