Open FrankKai opened 4 years ago
rest parameter语法允许我们将不确定的arguments当作数组。
function sum(...theArgs) {
return theArgs.reduce((acc, cur)=> acc+cur))
}
console.log(sum(1, 2, 3)); // 6
语法:function f(a, b, ...theArgs){ //... }
函数的最后一个形参可以使用...前缀把剩余的arguments存储在一个标准的js数组中。 只有最后一个参数是“rest parameter”。
在rest parameters出现之前,可以使用以下几种方式将arguments转化为数组。
function f(a, b) {
let normalArray = Array.prototype.slice.call(arguments)
// --or--
let normalArray = [].slice.call(arguments)
// --or--
let normalArray = Array.from(arguments)
}
当然可以。
function f(...[a, b, c]) {
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)
function multiply(multiplier, ...theArgs) {
return theArgs.map(function(element) {
return multiplier * element
})
}
let arr = multiply(2, 1, 2, 3)
console.log(arr) // [2, 4, 6]
// 自我思考:用好rest parameters,避免Array.prototype.forEach到底。
myFunction(...iterableObj);
[...iterableObj, '4', 'five', 6];
let objClone = { ...obj };
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // expected output: 6
console.log(sum.apply(null, numbers)); // expected output: 6
#### function calls中的spread语法
##### spread语法可以替代apply
```js
function myFunction(x, y, z) { }
const args = [0, 1, 2];
// 可以使用apply将一个普通数组转换为函数的arguments
myFunction.apply(null, args);
有了spread语法后,可以这样写:
function myFunction(x, y, z) { }
const args = [0, 1, 2];
myFunction(...args);
spread语法可以用很多次:
function myFunction(v, w, x, y, z) { }
const args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
apply有[[Call]]没有[[Construct]]。
const dateFields = [1970, 0, 1];
const d = new Date(...dateFields);
若是没有spread 语法,需要按照下面的方式为new使用数组:很复杂。
const parts = ['shoulders', 'knees'];
const lyrics = ["head", ...parts, "and", "toes"];
// ["head", "shoulders", "knees", "and", "toes"]
const arr = [1, 2, 3];
const arr2 = [...arr]; // 与arr.slice()效果一样
arr2.push(4); // arr2 [1,2,3,4] arr [1,2,3]
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
arr1 = arr1.concat(arr2);
使用spread 语法后:
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];
将数组的每一项都放置在某个数组前面:Array.prototype.unshift()
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
// Prepend all items from arr2 onto arr1
Array.prototype.unshift.apply(arr1, arr2)
// arr1 is now [3, 4, 5, 0, 1, 2]
用spread语法后,会异常简单:
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1];
// arr1 is now [3, 4, 5, 0, 1, 2]
对象的浅拷贝和合并,有了比Object.assign()更加方便的方法。
const obj1 = { foo: 'bar', x: 42 };
const obj2 = { foo: 'baz', y: 13 };
const clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }
const mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
Object.assign()会出发setters,而spread语法不会。
Objects本身不可迭代,只有一下几种才迭代:
下面的方式使用会报错:
const obj = {'key1': 'value1'};
const array = [...obj]; // TypeError: obj is not iterable
亲测。浅拷贝。
数组验证:
var foo = [1,2,3,{hi:'es5'}];
var bar = [...foo];
bar[3].hi = 'es6';
bar; // [1,2,3,{hi:'es6'}]
foo; // [1,2,3,{hi:'es6'}] 注意这里,由于...是浅拷贝,所以foo也跟着变成es6了
对象验证:
var foo = {hi: {version:'es5'}};
var bar = [...foo];
bar.hi.version = 'es6';
bar; // {hi: {version:'es6'}};
foo; // {hi: {version:'es6'}}; 注意这里,由于...是浅拷贝,所以foo也跟着变成es6了
const arr = [2,1,3];
// 取最大值
Math.min(...arr)
// 取最小值
Math.max(...arr)
let obj = {foo: 1, bar: 2, baz: 3, oof: 4}
function destructObj({foo, bar, ...others}){
console.log(foo, bar, others);
}
destructObj(obj);
// 1 2 {baz: 3, oof: 4}
let arr = [1,2,3,4,"foo"]
function destructArr([num1, num2, ...others]){
console.log(num1, num2, others);
}
destructArr(arr);
// 1 2 [3, 4, "foo"]
在学习nodeschool的count-to-6教程时,遇到了这两个常用但是一直没有系统学习的概念,因此在mdn找到相关文档进行学习。
...
操作符实践