rest
参数是指在函数参数定义中使用三个点(...)来将多个参数收集到一个数组中,而展开运算符则是在函数调用时使用三个点(...)将数组展开成多个参数。
如果你想将多个参数收集到一个数组中,就可以在函数参数定义中使用
rest
操作符。
let sum = (...numbers) => {
let result = 0;
numbers.forEach(function(n){
result += n;
});
return result;
};
console.log(sum(1,2,3));
处理嵌套函数内的arguments
对象变得非常棘手,让我们看看下面的情况,其中我们的内部函数需要访问传递的arguments
对象。
如果我们的inner function filterNumbers
需要访问arguments,则必须将其存储在variable
中,并在将其进一步传递之前,因为每个函数都有自己的arguments
对象,它是一个类似数组的对象。
function sumOnlyNumbers() {
var args = arguments;
var numbers = filterNumbers();
return numbers.reduce((sum, element) => sum + element);
function filterNumbers() {
return Array.prototype.filter.call(args,
element => typeof element === 'number'
);
}
}
sumOnlyNumbers(1, 'Hello', 5, false);
这种方法可行,但过于冗长。可以省略
var args = arguments
并使用
rest
参数将
Array.prototype.filter.call(args)
转换为
args.filter()
。
function sumOnlyNumbers(...args) {
var numbers = filterNumbers();
return numbers.reduce((sum, element) => sum + element);
function filterNumbers() {
return args.filter(element => typeof element === 'number');
}
}
sumOnlyNumbers(1, 'Hello', 5, false);
无论何时您想要将一个数组扩展成单独的参数,您都可以在函数调用中使用扩展运算符。
let sum = (a,b,c) => {
return a + b + c;
};
console.log(sum(...[1,2,3]));
在上面的代码中,扩展运算符将三个值的数组
"spread"
到
参数a、b和c
。 扩展运算符还可以展开数组以创建
array
文本中的单个元素。
var a = [4, 5, 6];
var b = [1, 2, 3, ...a, 7, 8, 9]
console.log(b);
ES6提供了更好的函数调用方式
ES5
通过函数对象提供.apply()
方法来解决这个问题。不幸的是,这种技术存在三个问题:
- 需要手动指定函数调用的上下文
- 无法在构造函数调用中使用
- 更短的解决方案更可取
在.apply()
中重复指定上下文显得多余且无意义。
let countries = ['India', 'USA'];
let otherCountries = ['China', 'Japan'];
countries.push.apply(countries, otherCountries);
console.log(countries); // => ['India', 'USA', 'China', 'Japan']
< p > < code > spread 运算符使用来自< code > array 的值填充< code > function 调用参数。让我们使用展开运算符改进上面的示例:
let countries = ['India', 'USA'];
let otherCountries = ['China', 'Japan'];
countries.push(...otherCountries);
console.log(countries); // => ['Moldova', 'Ukraine', 'USA', 'Japan']
Spread
运算符可以从一个数组中配置构造函数的调用参数,这种方法直接使用.apply()
比较复杂和困难。
class Actor {
constructor(name, country) {
this.name = name;
this.country = country;
}
getDescription() {
return `${this.name} leads ${this.country}`;
}
}
var details = ['RajiniKanth the Great', 'India'];
var Alexander = new Actor(...details);
console.log(Alexander.getDescription());
此外,您可以在同一调用中结合多个
spread
运算符和常规参数。以下示例从一个数组中删除现有元素,然后添加另一个数组和一个元素:
var numbers = [1, 2];
var evenNumbers = [4, 8];
const zero = 0;
numbers.splice(0, 2, ...evenNumbers, zero);
console.log(numbers);
克隆一个数组实例:
var words = ['Hi', 'Hello', 'Good day'];
var otherWords = [...words];
console.log(otherWords);
console.log(otherWords === words);
otherWords
是一个单词数组的克隆版本。请注意,克隆仅在数组本身上进行,而不是在包含的元素上进行(即不是深克隆)。
参考资料:https://dmitripavlutin.com/how-three-dots-changed-javascript/
...
并不是一个运算符。 - hippietrail