Object 语法扩展
属性简写
当我们使用字面量声明一个对象时,经常会有下面的写法
let person = { |
其中键的名字和值的名字都是相同的,name,age 写了两遍,在 ES6 中提供了简写语法,当键的名称与值对应变量名相同时,那么就可以简写,如上可以简写为
let person = { |
方法简写
在 ES5 中如下定义方法
let person = { |
在 ES6 中提供了更加简洁的写法
let person = { |
简写的方法与一般方法的不同在于,在简写方法中可以使用 super,而非简写方法不行。简写方法的 name 属性就是括号前的名称,例如上面 person.sayHello
的 name 属性是 sayHello
。
计算属性名
在 ES5 中是无法使用一个变量的值作为键名的,例如
let lastName = "last name" |
我们希望的是 person 对象有两个属性,分别是
- first name
- last name
但是实际上的两个属性为
- first name
- lastName
在 ES6 中可以通过方括号 [] 将变量括起来,使得变量的值成为对象的键
let lastName = "last name" |
新方法
Object.is
在比较两个值时,我们会使用 ==
或者更加严格的 ===
,更多的人乐意使用 ===
,但是即使是 ===
也会不准确,例如
+0 === -0 :true
NaN === Nan :false
Object.is 方法正是用来修补这一小的瑕疵的,它的作用与 ==
和 ===
一样也是用来比较两个值是否相同的
const print = console.log; |
Object.is 与 ===
的不同仅在于 +0,-0 以及 NaN 的比较。
Object.assign
在实际的工作中,需要将其他对象的属性复制到另一个对象中,这个操作常称之为mixin
function mixin(receiver, supplier) { |
在其他的库有相似的方法实现相同的功能,如 mix,extend 等等。ES6 引入了 Object.assign 方法,实现的功能与上述的相同,Object.assign 不能复制原型链上的属性以及不可枚举的属性。Object.assign 的语法如下
Object.assign(target, ...sources) |
接收一个 target 对象,以及任意多个 source,将多个 source 中的属性复制到 target 当中,如果 target 中的属性与 sources 中某对象的属性相同,那么 target 中的属性的值将会被覆盖,如果多个 source 有相同的属性名,那么后面的 source 属性值会覆盖签名的属性值。
let target = {} |
Object.assign 进行的是浅拷贝,如果需要进行深拷贝,需要另求他法。在使用 Object.assign 进行复制的过程中,会触发 getter 和 setter 方法。
Object.assign 的更多细节,参考 MDN Object.assign()
重复字面属性
在 ES6 之前,如果在定义对象时,有重复的属性名,那么会报错
let person = { |
但是在 ES6 中不会,后面定义的属性值会覆盖之前定义的属性值
let person = { |
自有属性遍历顺序
在 ES5 中没有规定当遍历一个对象时应该以何种顺序来访问对象的属性,但是在 ES6 中规定了访问的顺序,这个影响了 Object.getOwnPropertyNames()
和 Reflect.ownKeys()
,同样也影响了调用 Object.assign 进行复制时赋值的顺序。键的顺序如下:
- 按照升序排序的数字
- 按照添加顺序排序的字符串
- 按照添加顺序排序的 Symbol
let obj = { |
for-in 循环没有具体的遍历顺序,因为不同的 JavaScript 引擎有不同的实现。Object.keys()
和 JSON.stringfy()
规定使用和 for-in 循环一样的遍历顺序。
Prototypes 的增强
改变对象的原型
在创建对象时,我们可以通过 Object.create 为对象指定一个原型
let person = { |
可以通过 Object.getPrototypeOf() 获得对象的原型
console.log(Object.getPrototypeOf(friend) === person); // true |
在 ES6 中新增了 Object.setPrototypeOf()
方法,可以改变一个对象的原型
let dog = { |
super
如果对象重写了原型的方法,如何在对象中调用原型的同名方法,一般通过如下方式调用
let person = { |
我们通过 Object.getPrototypeOf(this).sayHello.call(this)
来调用父类的某个方法,在 ES6 中引入了 super,super 指定原型对象,所以 friend 对象中的代码可以简化如下
let friend = { |
super 只能在简写方法中使用,如下会发生语法错误
let friend = { |