对于 ES6 新特性中的 ... 可以简单的理解为下面一句话就可以了:
对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中。
作用类似于
Object.assign()
方法,我们先来看一下 Object.assign()
方法:
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。如下:
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source); console.log(target); // { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // { a: 1, b: 4, c: 5 }
语法
Object.assign(target, ...sources)
参数: target(目标对象), sources(源对象)
返回值: 目标对象。
Object.assign() 方法中如果有相同的对象属性前面的会被后面的替换掉。
接下来我们看一个最简单的例子:
let bar = { a: 1, b: 2 };
let baz = { ...bar };
console.log(baz); // { a: 1, b: 2 }
从上面可以看出 ... 扩展运算符就是将一个参数对象整体遍历再拷贝到当前对象中,再看下面的例子:
let bar = {a: 1, b: 2};
let baz = {...bar, ...{a: 2, b: 4}};
console.log(bar); // { a: 1, b: 2 }
console.log(baz); // { a: 2, b: 4 }
... 扩展运算符如果有想用的对象属性,那么后者会将前者覆盖掉。同时我们也可以看出这是一个浅拷贝,并不会将源对象更改掉。
但是如果是如下代码:
let obj1 = { a: 1, b: {name: 'aaa'}};
let obj2 = { ...obj1};
obj2.a = 2;
obj2.b.name = 'bbb';
console.log(obj1); // {a: 1, b: {name: 'bbb'}}
console.log(obj2); // {a: 2, b: {name: 'bbb'}}
从上面我们班可以看出,当 obj2 的 a 属性改变时,obj1 内的 a 属性不会跟着改变,但是当 obj2 的 b 属性改变时,obj1 内的 b 属性会跟着改变,这是由于 obj1 的 b 属性是引用数据类型,拷贝的时候拷贝的是对象的引用,但是基础数据类型会完整的复制出一份来。
扩展运算符也可以对数组进行运算,因为数组也属于对象的一种,如下:
var foo = function(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
} var arr = [1, 2, 3]; //传统写法
foo(arr[0], arr[1], arr[2]); //使用扩展运算符
foo(...arr);
//
//
//
从上面的代码可以看出 ... 扩展运算符可以简化我们的代码。
我们再来看下面的代码:
let arr1 = [1, 2];
let arr2 = arr1;
arr2[0] = 2;
console.log(arr1); // [2, 2]
上面我们已经解释过了,arr2 其实是 arr1 的引用,如果改变 arr2 那么 arr1 也会跟着改变,但是我们不想让 arr1 跟着改变怎么办呢?用 ... 扩展运算符就不会了:
let arr1 = [1, 2];
let arr2 = [...arr1];
arr2[0] = 2;
console.log(arr1); // [1, 2]
上面我们已经说过了,基础数据类型会重新完整的拷贝除一份来,这就完美的解决了上面的问题。
扩展运算符还可以将字符串转为数组,如下:
let str = "hello";
let arr = [...str];
console.log(arr); // [ 'h', 'e', 'l', 'l', 'o' ]
注意:
如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
如下:
let [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); //
console.log(rest); // [2, 3, 4, 5]
let [...first, last] = [1, 2, 3, 4, 5];
console.log(first); // 报错 Rest element must be last element
console.log(last);
let [first, ...rest, last] = [1, 2, 3, 4, 5];
console.log(first); // 报错 Rest element must be last element
console.log(rest);
console.log(last);