类数组对象:arguments
js把传入到这个函数的全部参数存储在arguments里面,其实arguments也是个对象,而且是一个特殊的对象,它的属性名是按照传入参数的序列来的,第1个参数的属性名是’0’,第2个参数的属性名是’1’,以此类推,并且它还有length属性,存储的是当前传入函数参数的个数,很多时候我们把这种对象叫做类数组对象。
数组比类数组对象多了很多其他的方法,类数组对象只是长得像数组而已。
在arguments对象里面,数据是这样存储的:
{ length: 4, '0': 'zero', '1': 'one', '2': 'two', '3': 'three' }
Array.prototype.slice.call()
在Array类中有一个方法叫做slice,用来截取数组中的一部分,用法是:
arrayObj.slice(start, [end])
call的用法是:
call([thisObj[,arg1[arg2[[argN]]]]]) //thisObj是一个对象的方法 ,arrg1~argN是参数
那么Array.prototype.slice.call()的意思就是说把调用方法的参数截取出来。
Array.prototype.slice.call(arguments,1);
为什么要用Array.prototype.slice,而不是直接引用?
因为Array是一个类,不能直接引用,需要获取原型后才能使用。
如果要直接引用,需要实例化Array,如下:
var array = new Array();
array.slice();
function test(a,b,c,d) { var arg = Array.prototype.slice.call(arguments,1); alert(arg); } test("a","b","c","d"); //b,c,d
多次用到 Array.prototype.slice.call(arguments, 1),不就是等于 arguments.slice(1) 吗?像前者那样写具体的好处是什么?为什么要这样写?
因为arguments并不是真正的数组对象,只是与数组类似而已,所以它并没有slice这个方法,而
Array.prototype.slice.call(arguments, 1)
可以理解成是让arguments转换成一个数组对象,让arguments具有slice()方法。要是直接写arguments.slice(1)会报错。
总的来说Array.prototype.slice.call(arguments)
能将具有length属性的对象转成数组。
将函数的实际参数转换为数组的方法
方法一:
var args = Array.prototype.slice.call(arguments);
方法二:
var args = [].slice.call(arguments, 0);
方法三:
var args = []; for (var i = 1; i < arguments.length; i++) { args.push(arguments[i]); }
最后,附个转成数组的通用函数
var toArray = function(s){ try{ return Array.prototype.slice.call(s); } catch(e){ var arr = []; for(var i = 0,len = s.length; i < len; i++){ //arr.push(s[i]); arr[i] = s[i]; //据说这样比push快 } return arr; } }