展开运算符的加入可以使我们在写JS代码时更加简洁灵活。可用于函数调用、解构赋值等方面。

谨慎使用对象展开符,其和一般的引用传递过程有一定的区别

一、展开运算符的拷贝机制

实例:

<script>
    let obj1 = {
      attri1: [6, 6, 0],
      attri2: 4,
      attri4: 5
    }
    let obj2 = { ...obj1 }
    // 因js的解析顺序,所以1obj2的输出结果是赋值后的结果
    console.log('1obj2: ', obj2)
    obj2.attri2 = 888
    obj2.attri1[0] = 7
    // 因展开运算符的拷贝,能拷贝简单数据类型,对于复杂数据类型仅拷贝其引用。
    // 所以对obj2的数据重新赋值,obj1中attri1值变化了,而attri2,attri4未变
    console.log('obj1:', obj1)
    console.log('2obj2: ', obj2)
</script>

输出结果:

1obj2:

js的展开运算符为什么可以展开普通对象 js 对象展开运算符_展开运算符

obj1:

2obj2:

js的展开运算符为什么可以展开普通对象 js 对象展开运算符_展开运算符_02

二、应用

1、函数调用中使用展开运算符

在以前我们会使用apply方法来将一个数组展开成多个参数:

function test(a, b, c) { }
var args = [0, 1, 2];
test.apply(null, args);

如上,我们把args数组当作实参传递给了a,b,c,这边正是利用了Function.prototype.apply的特性。

不过有了ES6,我们就可以更加简洁地来传递数组参数:

function test(a,b,c) { }
var args = [0,1,2];
test(...args);

我们使用...展开运算符就可以把args直接传递给test()函数。

2、数组字面量中使用展开运算符

在ES6的世界中,我们可以直接加一个数组直接合并到另外一个数组当中:

var arr1=['a','b','c'];
var arr2=[...arr1,'d','e']; //['a','b','c','d','e']

展开运算符也可以用在push函数中,可以不用再用apply()函数来合并两个数组:

var arr1=['a','b','c'];
var arr2=['d','e'];
arr1.push(...arr2); //['a','b','c','d','e']

3、用于解构赋值

解构赋值也是ES6中的一个特性,而这个展开运算符可以用于部分情景:

let [arg1,arg2,...arg3] = [1, 2, 3, 4];
arg1 //1
arg2 //2
arg3 //['3','4']

展开运算符在解构赋值中的作用跟之前的作用看上去是相反的,将多个数组项组合成了一个新数组。

不过要注意,解构赋值中展开运算符只能用在最后:

let [arg1,...arg2,arg3] = [1, 2, 3, 4]; //报错

展开运算符可以将一个类数组对象变成一个真正的数组对象:

var list=document.getElementsByTagName('div');
var arr=[..list];

list是类数组对象,而我们通过使用展开运算符使之变成了数组。

5、ES7草案中的对象展开运算符

ES7中的对象展开运算符符可以让我们更快捷地操作对象:

let {x,y,...z}={x:1,y:2,a:3,b:4};
x; //1
y; //2
z; //{a:3,b:4}

如上,我们可以将一个对象当中的对象的一部分取出来成为一个新对象赋值给展开运算符的参数

同时,我们也可以像数组插入那样将一个对象插入另外一个对象当中:

let z={a:3,b:4};
let n={x:1,y:2,...z};
n; //{x:1,y:2,a:3,b:4}

另外还要很多用处,比如可以合并两个对象:

let a={x:1,y:2};
let b={z:3};
let ab={...a,...b};
ab //{x:1,y:2,z:3}