[乐意黎]JS扩展运算符(spread)三个点号(...)的理解

作用:将一个数组转为用逗号分隔的参数序列。
 

语法

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

描述

如果函数的最后一个命名参数以...为前缀,则它将成为一个数组,其中从0(包括)到theArgs.length(排除)的元素由传递给函数的实际参数提供。

在上面的例子中,theArgs将收集该函数的第三个参数(因为第一个参数被映射到a,而第二个参数映射到b)和所有后续参数。剩余参数和 arguments对象的区别

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

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

引入了剩余参数来减少由参数引起的样板代码。

// Before rest parameters, the following could be found:
function f(a, b) {
  var args = Array.prototype.slice.call(arguments, f.length);

  // …
}

// to be equivalent of

function f(a, b, ...args) {
  
}

解构剩余参数

剩余参数可以被解构,这意味着他们的数据可以被解包到不同的变量中。请参阅解构赋值

function f(...[a, b, c]) {
  //console.log(...[1, 2, 3])  //1 2 3
  return a + b + c;
}

f(1)          // NaN (b and c are undefined)
f(1, 2, 3)    // 6
f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured)

示例

因为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); 
console.log(arr);  // [2, 4, 6]

下例演示了你可以在剩余参数上使用任意的数组方法,而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();// Uncaught TypeError: arguments.sort is not a function
  return sortedArgs; // 不会执行到这里
}
 
alert(sortArguments(5,3,7,1)); // 抛出TypeError异常:arguments.sort is not a function

为了在arguments对象上使用Array方法,它必须首先被转换为一个真正的数组。

function sortArguments() {
  var args = Array.prototype.slice.call(arguments);
  var sortedArgs = args.sort();
  return sortedArgs;
}
console.log(sortArguments(5, 3, 7, 1)); // shows 1, 3, 5, 7

示例:

不使用循环语句(包括map、forEach方法)实现一个100长度的数组,索引值和值相同的数组[0,1,2,3,4,5........99]

 

var arr = new Array(100);
//方法1
//扩展运算符(spread)是三个点(...)

[...arr.keys()];

//(100) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 
//22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
// 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 
//68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

 

1
2
3
4
5
6
7
8
9
10
//该运算符主要用于函数调用。<br>function push(array, ...items) {
   array.push(...items);
}
 
function  add(x, y) {
   return  x + y;
}
 
var  numbers = [4, 38];
add(...numbers)  // 42
 
1
2
3
4
5
6
7
8
9
//扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。
// ES5 的写法
Math.max.apply( null , [14, 3, 77])
 
// ES6 的写法
Math.max(...[14, 3, 77])
 
// 等同于
Math.max(14, 3, 77);

 

1
2
3
4
5
6
7
8
9
10
//通过push函数,将一个数组添加到另一个数组的尾部
// ES5的 写法
var  arr1 = [0, 1, 2];
var  arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);
 
// ES6 的写法
var  arr1 = [0, 1, 2];
var  arr2 = [3, 4, 5];
arr1.push(...arr2);

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//合并数组
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
 
var  arr1 = [ 'a' 'b' ];
var  arr2 = [ 'c' ];
var  arr3 = [ 'd' 'e' ];
 
// ES5的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
 
// ES6的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

 

1
2
3
扩展运算符将字符串转为真正的数组
[... 'hello' ]
// [ "h", "e", "l", "l", "o" ]
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页