对象的扩展

130 阅读4分钟

1.属性的简洁表示

ES6允许在对象括号里直接写入变量和函数,作为对象的属性和方法。但是这种写法在构造函数中会报错。

image.png

image.png

2.属性名表达式

JS中有两种方法定义属性名:标识符、表达式。但是在以前如果使用字面量方式(大括号)来定义对象,那么就必须用标识符定义变量名。ES6开始允许表达式定义属性名的方法在字面量方式中使用,但是表达式需要加上中括号[]

image.png

表达式也可以用于定义方法名:

image.png

需要注意的是:该方法不能和简洁表示法一起使用,否则会报错,且属性名表达式是一个对象的话,也会输出异常。

3.属性的可枚举性和可遍历性

3.1枚举性

对象的每个属性都有一个可由Object.getOwnPropertyDescriptor获得的描述对象(Dexcriptor),用来控制该对象的行为。该方法可获得属性的四个描述:分别为属性值value、可写性writable、可枚举性enumberable和可配置性configurable

image.png

若该属性值的可枚举性enumberablefalse,则有一些操作会直接跳过该属性。目前有四个操作会忽略跳过:

  • for...in循环:只会遍历对象自身和继承的可枚举属性
  • Object.keys():返回对象自身所有可枚举的属性的键名
  • JSON.stringify():只串行话对象自生的可枚举属性
  • Object.assign():忽略不可枚举属性,只拷贝对象自身的可枚举属性

Object.assign()是ES6才引入的。其中,只有for...in才会返回继承属性,其余三个都只会操作对象的自身属性。所以对于对象的遍历,如果只关心自身属性,就尽量不要使用for..of,而使用Object.keys()

3.2遍历性

ES6共有五种方法可以遍历对象属性:

  1. for...in循环:遍历自身和继承的可枚举属性(不含Symbol属性)
  2. Object.key(obj):以数组方式返回仅对象自身的所有可枚举属性的键名(不含Symbol属性)
  3. Object.getOwnPropertyNames(obj):以数组方式返回仅对象自身的所有属性(包含不可枚举属性)的键名(不含Symbol属性)
  4. Object.getOwnPropertySymbols(obj):以数组方式返回包含仅对象自身所有的Symbol属性的键名
  5. Reflect.ownKeys(obj):以数组方式返回仅对象自身的所有键名

以上五种方式遍历键名都遵顼同一个遍历规律:首先遍历数值,按升序排序 ---> 其次遍历字符串,按照加入时间升序排序 ---> 最后遍历Symbol键,按加入时间升序排序。即数值字符串Symbol

image.png

4.super关键字

ES6新增了super关键字,其作用类似于this,但是他绑定的是当前对象的原型对象。

image.png

该实例利用Object.setPrototypeOf()方法将protot设置为child的原型,然后使用superchild的方法中输出了其原型的属性值。值得注意的是:super只能用于对象的方法中,在其他任何地方都会报错。

5.对象的扩展运算符

5.1解构赋值

ES2018将扩展运算符...引入到了对象中,对象的结构赋值会将对象中未分配的、可遍历的所有属性分配到指定的对象中,以键值对的形式拷贝下来。同样的,结构赋值需要是最后一个参数才可以。

image.png

解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。即对拷贝值进心的操作也会同样映射到原来的值上,反之亦然。

5.2扩展运算符

对象的扩展运算符用于取出参数对象的可遍历属性并将其拷贝到新的对象中。数组也可拷贝,因为数组是特殊的对象。若运算符右边不是对象,则会将其转换为对象。

image.png

image.png

同数组扩展时一样,扩展运算符可以用来合并两个对象。

image.png

以上方法仅拷贝了对象的属性,若是想完整拷贝一个对象及其原型的话,可采取以下写法:

image.png

若用户自定义属性在扩展运算符后面,则会覆盖掉扩展运算符中的同名属性,反之亦然。

image.png