对于 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);

javascript ES6 新特性之 扩展运算符 三个点 ...的更多相关文章

  1. JavaScript ES6新特性介绍

    介绍 ES6:ECMScript6 首先,一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系? ECMAScript是一个国际通过的标准化脚本语言: JavaScript ...

  2. JavaScript ES6 新特性详解

    JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读 const ,  let and var 的区别: const , let 是 ES6 中用于声明变量的新关键字. ...

  3. javascript ES6 新特性之 let

    let的作用是声明变量,和var差不多. let是ES6提出的,在了解let之前,最好先熟悉var的原理. JavaScript有一个机制叫“预解析”,也可以叫“提升(Hoisting)机制”.很多刚 ...

  4. ES6新特性使用小结(三)

    九.数据类型 Symbol /* * Symbol 数据类型 概念: Symbol 提供一个独一无二的值 * */ { let a1 = Symbol(); let a2 = Symbol(); co ...

  5. javascript ES6 新特性之 Promise,ES7 async / await

    es6 一经推出,Promise 就一直被大家所关注.那么,为什么 Promise 会被大家这样关注呢?答案很简单,Promise 优化了回调函数的用法,让原本需要纵向一层一层嵌套的回调函数实现了横向 ...

  6. javascript ES6 新特性之 class

    在之前的文章中我们讲过原型,原型链和原型链继承的文章,在 ES6 中为我们提供了更为方便的 class,我们先来看一下下面的例子: function Person(name) { //构造函数里面的方 ...

  7. javascript ES6 新特性之 解构

    解构的作用是可以快速取得数组或对象当中的元素或属性,而无需使用arr[x]或者obj[key]等传统方式进行赋值 var arr = [1, 2, 3]; //传统方式 var a = arr[0], ...

  8. es6 学习小记 扩展运算符 三个点(...)

    参考: es6 扩展运算符 三个点(...) 经常回顾,方能真正掌握. 一.含义 扩展运算符( spread )是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. ...

  9. ES6新特性三: Generator(生成器)函数详解

    本文实例讲述了ES6新特性三: Generator(生成器)函数.分享给大家供大家参考,具体如下: 1. 简介 ① 理解:可以把它理解成一个函数的内部状态的遍历器,每调用一次,函数的内部状态发生一次改 ...

随机推荐

  1. 12.app后端如何选择合适的数据库产品

    app后端的开发中,经常要面临的一个问题是:数据放在哪里? mysql ?redis?mongodb? 现在有这么多优秀的开源数据库产品,怎么根据业务场景来选择合适的数据? 常用的数据库产品的优缺点又 ...

  2. Kafka基础

    简介 #概念:消息中间件(消息系统)      //消息系统分类:         点对点 消息队列(peer-to-peer)         发布/订阅 消息队列 消费者在消费时,是通过pull ...

  3. java异常基础整理

    1.try-catch e.printStackTrace(); 会打印出方法的调用痕迹,如此例,会打印出异常开始于TestException的第16行,这样就便于定位和分析到底哪里出了异常 2.使用 ...

  4. MVC项目中怎么浏览html页面

    public class HomeController : Controller { public ActionResult Index() { //return View(); //return R ...

  5. Link-Cut Tree指针模板

    模板: 以下为弹飞绵羊代码: #define Troy #include "bits/stdc++.h" using namespace std; ; inline int rea ...

  6. 【BZOJ】1969: [Ahoi2005]LANE 航线规划

    题目链接: 传送~~ 题解:  老夫实在是码不动了…… 正着搞显然不好做,尝试倒着乱搞.先给被删除的边标记一个时间戳,先删除的时间戳大,同时维护询问时间戳,询问早的时间戳大.没被删除过的边时间戳都是0 ...

  7. bzoj5252 [2018多省省队联测]林克卡特树

    斜率优化树形dp?? 我们先将问题转化成在树上选K+1条互不相交路径,使其权值和最大. 然后我们考虑60分的dp,直接维护每个点子树内选了几条路径,然后该点和0/1/2条路径相连 然后我们会发现最后的 ...

  8. kmspico_setup.exe运行提示系统资源不足,无法完成请求的服务

    在使用KMSpico激活office时,windows下运行exe会提示系统资源不足,无法完成请求的服务. 我的解决方法是:卸载电脑上的wps...

  9. MFC多语言程序版本,在不同的windows系统上的使用

    如何使MFC程序界面支持多国语言?这次使用后给自己做一个总结. 我们使用vc6.0的版本来试验 1. 切换到资源视图,右键Dialog->Insert Copy 2. ok后,会出来一个语言的选 ...

  10. php SESSION入库的实现

    session入库,就是重写session制机,在session的周期内,获得到session的数据并记录到数据库 Session默认是存放到服务器上的文件中,不方便管理,如果能把session存放到 ...