apply 可以接受两个参数,
fun.apply(thisArg[, argsArray])
其中第二个参数是数组或类数组对象,所以有时传 arguments 也很正常,但是,认真的说,我测试出来:
类数组对象:一个拥有 length 属性且值可以转为整数的对象;
实际应用中, apply 明显是将类数组中的对象一个个传入到 fun 中的,这个应该没有歧义;正常情况下,也没有什么异常,直到遇见下面代码:
Array.apply(null,{length:2});// [undefined, undefined]
而且,上面的返回值跟下面这样还是有区别的:
Array(2);//[empty × 2]
有些数组操作方法是直接忽略掉空项,但不忽略值为 undefined 的项,譬如下面的 forEach:
Array.apply(null,{length:2}).forEach(v=>console.log(1));// 输出1,两次 Array(2).forEach(v=>console.log(1))//不输出
从上面代码里,我们可以推算出 apply 的内部机制,
apply 是按照类数组对象的 length 属性,把 0 到 length-1 的数字属性的值作为参数挨个传给 func,如果没有定义其中的数字属性(这种情况一般存在于自定义的类数组对象中),那么就传 undefined
所以才会有上面的代码;不过相比:
Array.apply(null,{length:2}).forEach(v=>console.log(1));// 输出1,两次
我觉得用 ES6 会更好理解些:
Array.from({length:2}).forEach(v=>console.log(1));//同上
或者
Array(2).fill().forEach(v=>console.log(1));//同上
题外话,前面为什么猜测类数组对象的值可以转为整数就可以了呢,因为测试出来:
Array.from({length:true});//[undefined]