JS 函数参数arguments与rest 剩余参数解析

120 阅读2分钟

函数参数arguments与rest 参数解析

arguments

function add(num1, num2) {
  console.log(arguments); // { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7 }
}
​
add(1, 2, 3, 4, 5, 6, 7);

从arguments对象输出的内容我们可以看出

  • arguments内部的元素,跟函数实际传入参数的数值一致
  • 其index对应的数值,跟实际参数出传入的顺序也是一一对应的
  • 函数每次执行有自己的arguments对象

arguments的原型指向的是Object,而array的原型指向的是Array,所以arguments严格来说不是个数组,一般我们把它称作是伪数组或者类数组

arguments与Array的异同点

同:

  1. 都可通过length获取长度
  2. 保存值的方式都是index:value的形式
  3. 两者都可使用for...of进行遍历

异:

  1. arguments是类数组,不是真的数组
  2. Array上的方法大多不能使用,比如:mapforEach

arguments转为Array

方法一 自己遍历

function add(num1, num2) {
  const newArr = [];
  for (let i = 0; i < arguments.length; i++) {
    newArr.push(arguments[i] * 10); // 遍历的时候将每个元素*10
  }
​
  console.log(newArr);
}
​
add(1, 2, 3, 4, 5, 6, 7);

方法二 slice

var newArr = Array.prototype.slice.call(arguments);

Array.prototype.slice的内部实现(大致):

Array.prototype.slice = function(start,end) {
    // 获取到数组(包含类数组)
    var arr = this;
    
    // 不传递参数,则使用默认值
    start = start || 0
    end = end || arr.length
    
    var newArr = []
    for(var i = start; i < end; i++) { // 遍历数组
        newArr.push(arr[i])
    }
    
    return newArr
}

方法三 ES6语法

Array.from :

var newArr = Array.from(arguments)

扩展运算符 :

var newArr = [...arguments]

箭头函数没有arguments

var foo = (num1,num2) => {
  console.log(arguments);
};
​
foo(1,2);

箭头函数中没有arguments,那么就会向上查找:

  • 在浏览器中,全局是没有arguments变量的,所以报undefined的错误
  • 在node环境中是有数据的

我们使用闭包的方法,可以在内部函数中访问外层函数的arguments

function foo (num) {
    retrun () => {
        console.log(arguments) // 123
    }
}
​
var fn = foo(123)
fn()

rest 剩余参数

function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}
​
function(a, b, ...theArgs) {
  // ...theArgs保存的是剩余的实参
}

剩余参数与arguments的异同

  • 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。
  • arguments对象不是一个真正的数组,而剩余参数是真正的Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach或pop。
  • arguments对象还有一些附加的属性 (如callee属性)。
  • 剩余参数必须放在最后