Javascript学习---Rest参数和拓展操作

本文介绍了 JavaScript 中的 Rest 参数和拓展操作符的功能与用法。Rest 参数允许函数接收不定数量的参数,并将它们作为数组收集。拓展操作符用于将数组或其他可迭代对象展开为单独的元素。

javascript的许多内置函数都支持任意数量的参数,比如Math.max(arg1, arg2, ..., argN),Object.assign(dest, src1, ..., srcN)等等


Rest参数“...”

一个函数可以被任意个参数调用,例如:

function sum(a, b) {
  return a + b;
}

alert( sum(1, 2, 3, 4, 5) );

使用多个参数来调用函数并不会报错,当然只有前面两个参数会被使用。在javascript里我们可以使用rest参数来定义不确认个数的参数,即使用三个点“...”,它表示将多余的参数接受并放到一个数组里,例如:

function sumAll(...args) { // args is the name for the array
  let sum = 0;

  for (let arg of args) sum += arg;

  return sum;
}

alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6


我们也可以指定确定参数个数,例如:

function showName(firstName, lastName, ...titles) {
  alert( firstName + ' ' + lastName ); // Julius Caesar

  // the rest go into titles array
  // i.e. titles = ["Consul", "Imperator"]
  alert( titles[0] ); // Consul
  alert( titles[1] ); // Imperator
  alert( titles.length ); // 2
}

showName("Julius", "Caesar", "Consul", "Imperator");

需要注意的是rest参数必须放在参数列表的最后面,否则会报错误,例如:

function f(arg1, ...rest, arg2) { // arg2 after ...rest ?!
  // error
}

“arguments”参数变量

javascript的函数都有一个默认的参数变量arguments,它包含函数所有的参数变量,例如:

function showName() {
  alert( arguments.length );
  alert( arguments[0] );
  alert( arguments[1] );

  // it's iterable
  // for(let arg of arguments) alert(arg);
}

// shows: 2, Julius, Caesar
showName("Julius", "Caesar");

// shows: 1, Ilya, undefined (no second argument)
showName("Ilya");

在rest参数没出现的时候,javascript是使用arguments参数来获取所有的参数,由于历史原因它被保留至今。与rest参数不同的是,arguments参数是类数组和可迭代的,而不是真正的数组,故不能使用arguments.map(...)


箭头函数没有arguments

需要注意的是,箭头函数是没有arguments参数的,当我们访问箭头函数的arguments时,它默认使用外部函数的arguments,例如:

function f() {
  let showArg = () => alert(arguments[0]);
  showArg();
}

f(1); // 1
在前面我们已经知道剪头函数没有this,而且它的this是使用外部函数的this,在这里,arguments也是一样一样的~


拓展操作

前面我们已经知道如何从参数列表里获取一个数组,当有时候我们需要做的事情却是相反的,例如下面这个例子:

alert( Math.max(3, 5, 1) ); // 5

let arr = [3, 5, 1];

alert( Math.max(arr) ); // NaN

Math.max()对指定参数是正常运作的,但对于数组参数则发生错误,这是因为Math.max()接受的是参数列表,而不是一个数组。


为了解决这个问题,拓展操作就被引入进来了,看下面这个例子:

let arr = [3, 5, 1];

alert( Math.max(...arr) ); // 5 (spread turns array into a list of arguments)

这里的...arr就是拓展操作,只要参数是可迭代的,就可以使用拓展操作,例如Array,string等等


我们也可以传递多个拓展操作参数,例如:

let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(...arr1, ...arr2) ); // 8


也可以跟普通参数组合,例如:

let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25

对于数组合并函数也是一样,例如:

let arr = [3, 5, 1];
let arr2 = [8, 9, 15];

let merged = [0, ...arr, 2, ...arr2];

alert(merged); // 0,3,5,1,2,8,9,15 (0, then arr, then 2, then arr2)

其实拓展操作的原理是将参数进行迭代并逐一返回该值,类似于for...of,这也是为什么拓展操作要求参数必须为可迭代,例如对string进行拓展操作:

let str = "Hello";

alert( [...str] ); // H,e,l,l,o

..str操作后返回“H,e,l,l,o”,再将返回的内容放入数组中


在前面我们学习了Array.from()这个方法,我们也可以用它来转换字符串为数组,与上面例子的结果一样,如下:

let str = "Hello";

// Array.from converts an iterable into an array
alert( Array.from(str) ); // H,e,l,l,o

但是这里Array.from()和拓展操作还是有细微的区别的:

(1)Array.from()支持可迭代对象和类数组对象;

(2)拓展操作只支持可迭代对象;

对于将对象转换为数组,Array.from()一般使用得更多


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值