argument对象
为什么argument不是数组?
因为argument是一个对象,只不过它的属性从0开始排,依次为0,1,2…最后还有callee和length属性。我们也把这样的对象称为类数组。
初识arguments
arguments是一个类数组,表示传给function的参数列表
比如:
function demo(){
console.log(arguments);
}
demo("a","A",0,{foo:"Hello!world"})
执行结果是:
Arguments(4) [“a”, “A”, 0, {…}, callee: ƒ, Symbol(Symbol.iterator): ƒ]
控制台打印出来一个数组,包含着传入函数的实参,但是这并不是一个数组,所以说arguments是一个类数组的对象。
类数组的属性必须有:属性必须为索引(数字)属性,必须有length属性,最好加上push属性
但是并不是所有的数组方法都可以直接用,除非自身给他增加方法。
比如:
obj = {
"0" : 'a',
"1" : 'b',
"2" : 'c',
"length" : 3,
"push" : Array.prototype.push
}
首先明确一点,类数组属于对象和数组之间的领域(虽然数组本来就是特殊的对象),他既拥有对象的存储能力也拥有数组的存储能力。
有一个例题:
obj = {
"2" : "a",
"3" : "b",
"4" : "c",
"length" : 3,
"push" : Array.prototype.push
}
obj.push("d");
obj.push("e");
问:最后obj的结构是什么?
首先我们要弄清楚push的原理,push是数组Array的一个改变原数组的方法,是在数组末端添加一个数,然后length加一,那么我们可以把push理解为:
Array.prototype.push = function (target){
this[this.length] = target;
this.length++
}
我们先了解这个之后然后这道题就简单多了,那么答案就是
obj = {
"2" : "a",
"3" : "d",
"4" : "e",
"length" : 5,
"push" : Array.prototype.push
}
argument的操作
arguments.length
function func(){
console.log("传入参数有"+arguments.length+"个")
}
func();
func(1,2);
func(0,123,12);
执行结果为:
传入参数有0个
传入参数有2个
传入参数有3个
arguments转数组
Array.prototype.slice.call()
还可以写作[].slice.call(arguments);
function sum(a, b) {
let args = Array.prototype.slice.call(arguments);
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
Array.from()
function sum(a, b) {
let args = Array.from(arguments);
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
ES6的扩展运算符
function sum(a, b) {
let args = [...arguments]; //args——>[a,b]
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
concat+apply的方法——>上面的方法的ES5的体现
function sum(a, b) {
let args = Array.prototype.concat.apply([], arguments);//apply方法会把第二个参数展开
console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3