在将函数柯里化的时候,经常需要用到函数参数对象arguments转为数组的情况(如果是用apply方法来调用函数,其实没必要转为数组,因为apply方法的第二个参数不仅可以是数组,也可以是类数组对象)。下面给出几种转为数组的方式:
- ES5规范下的方式:
利用数组的slice方法,可以数组原型Array.prototype或者[]来调用slice,使用slice会阻止某些引擎(如V8)的优化,因此也可以遍历arguments来构造新数组,当然也可以用Array构造函数的方式;
var args = Array.prototype.slice.call(arguments); // 第一种方式;
var args = [].slice.call(arguments); // 第二种方式;
var args = arguments.length === 1? [arguments[0]]: Array.apply(null, arguments); // 第三种方式
- ES6规范下的方式:
利用数组的from方法或者…展开运算符
Array.from()从一个类数组对象或者可迭代对象浅拷贝出一个数组实例;
var args = Array.from(arguments); // 第四种方式;
var args = [...arguments]; // 第无种方式;
在用第三种方式构建新数组时,出现了Array.apply(null, arguments)写法,那为什么不直接用Array(arguments)呢?
function foo () {
var args = Array.apply(null, arguments);
console.log(args);
}
foo (1, 2); // [ 1, 2 ]
function foo () {
var args = Array(arguments);
console.log(args);
}
foo (1, 2); // [arguments]
Array(arguments)和Array.apply(null, arguments)的区别:
- 首先强调一点,在调用Array()来构建Array对象时,用new操作符和不用new操作符的行为一样;
- Array(arg1, arg2…)构建的数组,其中数组元素就是传入的参数,但如果参数是数组(类数组对象),那么Array()和Array.apply()构建出来的数组就有很大不同。
Array([1, 2]); // [[1, 2]]; 只有一个元素,元素为[1, 2];
Array.apply(null, [1, 2]); // [1, 2]; 两个元素,分别为1和2;
原因在于apply方法传入的第二个参数是数组或者类数组,元素会被展开成参数列表调用Array(),即相当于Array(1, 2),当然就会不同;
Array.apply(null, {length: 6}); // [undefined, undefined, undefined, undefined, undefined, undefined]; 有索引值,每个索引值上的值为undefined;
Array(6); 只生成一个6元素的空数组,但索引值没有,相当于只是占位,表明是一个6个元素的空数组;
这里的{length: 6}可以看做是类数组对象,这样就跟上面的分析一致了;