看Vue的官方文档的时候看到这么个奇技淫巧.
就是通过{length:20}来伪装成为包含了20个undefined元素的数组arguments.
举个例子的话就是这样:
function returnArguments(){
return arguments;
}
var args = returnArguments.apply(null,{length:20})
console.log(args);
//[undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
这背后的原理是怎样的? apply函数在将第二个参数转变为arguments时做了怎样的处理?
要知道new Array(20)
或者[].length=20
都不会往数组里面添加任何的内容的,new Array(20).forEach(()=>console.log(1))
也是不会打印任何内容的.
而为什么上述Vue官网的使用中却能得到真正填充了undefined的数组?
题主认为我没有解释原因。看来我应该把格式搞清晰一点,所以修改一下,分个段
如果你检查一下 returnArguments()
的返回值,你会发现那不是一个数组
function returnArguments() {
return arguments;
}
var a1 = returnArguments.apply(null, { length: 20 });
console.log(Array.isArray(a1));
// 输出 false
arguments
是一个伪数组,并不是真正的数组。如果用 es6,可以这样得到数组
function createArray(...args) {
return args;
}
var a2 = createArray.apply(null, { length: 20 });
console.log(Array.isArray(a2));
// 输出 true
不过,一般来说,我会使用这个方法
var a3 = Array.apply(null, { length: 20 });
arguments
是个伪数据,但打印出来跟数组的表现一样。下面的分析基于可以产生真正数组的Array()
,但使用returnArguments()
的原理是一样的。
apply()
的方式原理其实很简单,就拿 Array()
来说,它接受若干个参数,并把这些参数组成一个数组返回出来,所以如果我们想把 1,2,3,4,5
变成数组可以这样
var a = Array(1,2,3,4,5);
apply()
,但直接给数组作为参数改写成 apply()
方式就是
Array.apply(null, [1,2,3,4,5]);
而 apply()
的第二个参数,可以是一个伪数组,所以可以传入这样一个数据来代替 [1,2,3,4,5]
var data = {
length: 5,
"0": 1,
"1": 2,
"2": 3,
"3": 4,
"4": 5
};
length
现在我们只需要生成一个指定长度的数组,而不关心数据(undefined
),所以这个作为伪数组的参数就可以写成
{ length: 5 }
即产生长度为5的数据可以用 Array.apply
这样生成
var r = Array.apply(null, { length: 5 });
undefined
的应该怎么做如果需要指定从 1 开始的 5 个数作为元素,可以这样
var list = Array.apply(null, { length: 5}).map((v, index) => index + 1);