一、函数绑定”运算符(::)

“函数绑定”(function bind)运算符,用来取代call、apply、bind调用

函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。

systemverilog双冒号运算符 es6双冒号运算符_数组

如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上面。

systemverilog双冒号运算符 es6双冒号运算符_数组_02

 

二、数组扩展运算符(…)

含义

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

systemverilog双冒号运算符 es6双冒号运算符_数组_03

该运算符主要用于函数调用。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_04

上面代码中,array.push(...items)和add(...numbers)这两行,都是函数的调用,它们的都使用了扩展运算符。该运算符将一个数组,变为参数序列。

扩展运算符与正常的函数参数可以结合使用,非常灵活。

systemverilog双冒号运算符 es6双冒号运算符_数组_05

扩展运算符后面还可以放置表达式。

systemverilog双冒号运算符 es6双冒号运算符_数组_06

如果扩展运算符后面是一个空数组,则不产生任何效果。

systemverilog双冒号运算符 es6双冒号运算符_运算符_07

注意,扩展运算符如果放在括号中,JavaScript 引擎就会认为这是函数调用。如果这时不是函数调用,就会报错。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_08

2  替代数组的 apply 方法

由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_09

扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。

systemverilog双冒号运算符 es6双冒号运算符_数组_10

另一个例子是通过push函数,将一个数组添加到另一个数组的尾部

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_11

 

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_12

3  扩展运算符的应用

复制数组:

ES5 只能用变通方法来复制数组。

systemverilog双冒号运算符 es6双冒号运算符_赋值_13

扩展运算符提供了复制数组的简便写法。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_14

合并数组

扩展运算符提供了数组合并的新写法。

systemverilog双冒号运算符 es6双冒号运算符_运算符_15

与解构赋值结合

扩展运算符可以与解构赋值结合起来,用于生成数组。

systemverilog双冒号运算符 es6双冒号运算符_数组_16

 

systemverilog双冒号运算符 es6双冒号运算符_运算符_17

如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_18

函数的返回值

JavaScript 的函数只能返回一个值,如果需要返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法

systemverilog双冒号运算符 es6双冒号运算符_赋值_19

字符串

扩展运算符还可以将字符串转为真正的数组。

systemverilog双冒号运算符 es6双冒号运算符_数组_20

上面的写法,有一个重要的好处,那就是能够正确识别 32 位的 Unicode 字符。

systemverilog双冒号运算符 es6双冒号运算符_赋值_21

实现了 Iterator 接口的对象

任何 Iterator 接口的对象,都可以用扩展运算符转为真正的数组。

systemverilog双冒号运算符 es6双冒号运算符_运算符_22

Map 和 Set 结构, Generator 函数

 

扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构

systemverilog双冒号运算符 es6双冒号运算符_数组_23

 

Generator 函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_24

 

 

 

systemverilog双冒号运算符 es6双冒号运算符_赋值_25

三、对象的扩展运算符(…)

解构赋值 § 

对象的解构赋值用于从一个对象取值,相当于将目标对象自身的所有可遍历的(enumerable)、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_26

上面代码中,变量z是解构赋值所在的对象。它获取等号右边的所有尚未读取的键(a和b),将它们连同值一起拷贝过来。

由于解构赋值要求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象。

systemverilog双冒号运算符 es6双冒号运算符_赋值_27

解构赋值必须是最后一个参数,否则会报错。

systemverilog双冒号运算符 es6双冒号运算符_数组_28

扩展运算符 § 

对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。

 

systemverilog双冒号运算符 es6双冒号运算符_运算符_29

如果扩展运算符后面是一个空对象,则没有任何效果

systemverilog双冒号运算符 es6双冒号运算符_赋值_30

如果扩展运算符后面不是对象,则会自动将其转为对象。

systemverilog双冒号运算符 es6双冒号运算符_赋值_31

 

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_32

但是,如果扩展运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象。

systemverilog双冒号运算符 es6双冒号运算符_运算符_33

对象的扩展运算符等同于使用Object.assign()方法

systemverilog双冒号运算符 es6双冒号运算符_数组_34

上面的例子只是拷贝了对象实例的属性,如果想完整克隆一个对象,还拷贝对象原型的属性,可以采用下面的写法。

systemverilog双冒号运算符 es6双冒号运算符_赋值_35

扩展运算符可以用于合并两个对象。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_36

如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。

systemverilog双冒号运算符 es6双冒号运算符_运算符_37

上面代码中,a对象的x属性和y属性,拷贝到新对象后会被覆盖掉。

这用来修改现有对象部分的属性就很方便了。

systemverilog双冒号运算符 es6双冒号运算符_运算符_38

上面代码中,newVersion对象自定义了name属性,其他属性全部复制自previousVersion对象。

如果把自定义属性放在扩展运算符前面,就变成了设置新对象的默认属性值。

systemverilog双冒号运算符 es6双冒号运算符_systemverilog双冒号运算符_39

与数组的扩展运算符一样,对象的扩展运算符后面可以跟表达式。

systemverilog双冒号运算符 es6双冒号运算符_赋值_40

扩展运算符的参数对象之中,如果有取值函数get,这个函数是会执行的。

systemverilog双冒号运算符 es6双冒号运算符_数组_41