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