实际参数在函数中我们可以使用 arguments 对象获得 (注:形参可通过 arguments.callee 获得),虽然 arguments 对象与数组形似,但仍不是真正意义上的数组。arguments本身不是一个数组,可以说是有length属性的一个对象(类数组对象),所以需要将其变通,改造成一个数组。
我们可以通过slice 方法将 arguments 对象转换成真正的数组。首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组,这里我们看第2个。Array.prototype.slice.call(arguments)能够将arguments转成数组,那么就是arguments.toArray().slice();到这里,是不是就可以说Array.prototype.slice.call(arguments)的过程就是先将传入进来的第一个参数转为数组,再调用slice?
方法一:
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]); }
注:一般的函数的 arguments.length 都在 10 以内,方法二有优势; 方法二的代码量上也比第一种少,至少可以减小一点字节
下面附一个例子:
function revse() { var args = Array.prototype.slice.call(arguments); newarr = []; for (var i = args.length - 1; i >= 0; i--) { newarr.push(args[i]); } return args; } var s = revse('a', 'b', 'c'); console.log(s);
再来看下面这个例子:
var a = {length: 2, 0 : 'first', 1 : 'second'}; //类数组,有length属性,长度为2,第0个是first,第1个是second console.log(Array.prototype.slice.call(a, 0)); // ["first", "second"],调用数组的slice(0); var a = {length: 2, 0 : 'first', 1 : 'second'}; console.log(Array.prototype.slice.call(a, 1)); //["second"],调用数组的slice(1); var a = {0 : 'first', 1 : 'second'}; //去掉length属性,返回一个空数组 console.log(Array.prototype.slice.call(a, 0)); //[] function test() { console.log(Array.prototype.slice.call(arguments, 0)); //["a", "b", "c"],slice(0) console.log(Array.prototype.slice.call(arguments, 1)); //["b", "c"],slice(1) } test("a", "b", "c");
最后,附个转成数组的通用函数:
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; } }