剩余参数(rest parameter)允许长度不确定的实参表示为一个数组。

语法

function(a, b, ...theArgs) {
  // ...
}

描述

如果一个函数的最后一个形参是以 ... 为前缀的,则在函数被调用时,该形参会成为一个数组,数组中的元素都是传递给该函数的多出来的实参的值。

在上例中,theArgs 会包含传递给函数的从第三个实参开始到最后所有的实参 (第一个实参映射到 a, 第二个实参映射到 b)。

剩余参数和 arguments 对象的区别

剩余参数和 arguments 对象之间的区别主要有三个:

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

arguments对象转换为剩余参数

使用剩余参数可以避免将arguments转为数组的麻烦

// 下面的代码模拟了剩余数组
function f(a, b){
  var args = Array.prototype.slice.call(arguments, f.length);
  // ...
}
 
// 现在代码可以简化为这样了
function(a, b, ...args) {
   
}

示例

因为theArgs是个数组,所以你可以使用length属性得到剩余参数的个数:

function fun1(...theArgs) {
  alert(theArgs.length);
}
 
fun1();  // 弹出 "0", 因为theArgs没有元素
fun1(5); // 弹出 "1", 因为theArgs只有一个元素
fun1(5, 6, 7); // 弹出 "3", 因为theArgs有三个元素

下例中, 剩余参数包含了从第二个到最后的所有实参. 然后用第一个实参依次乘以它们:

function multiply(multiplier, ...theArgs) {
  return theArgs.map(function (element) {
    return multiplier * element;
  });
}

var arr = multiply(2, 1, 2, 3); 
// [2, 4, 6]
console.log(arr); 

下例演示了你可以在剩余参数上使用任意的数组方法,而arguments对象不可以:

function sortRestArgs(...theArgs) {
  var sortedArgs = theArgs.sort();
  return sortedArgs;
}
 
alert(sortRestArgs(5,3,7,1)); // 弹出 1,3,5,7
 
function sortArguments() {
  var sortedArgs = arguments.sort();
  return sortedArgs; // 不会执行到这里
}
 
alert(sortArguments(5,3,7,1)); // 抛出TypeError异常:arguments.sort is not a function

如果想在arguments对象上使用数组方法,你首先得将它转换为真实的数组,比如使用 [].slice.call(arguments)

规范

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
Function Definitions
Standard Initial definition.
ECMAScript 2017 Draft (ECMA-262)
Function Definitions
Draft  

浏览器兼容性

Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 47 (Yes) 15 (15) 未实现 34 未实现
Feature Android Android Webview Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support 未实现 47 15.0 (15.0) 未实现 未实现 未实现 47

相关链接

文档标签和贡献者

 此页面的贡献者: Ende93, helloguangxue, sabrinaluo, teoli, fskuok, ziyunfei
 最后编辑者: Ende93,