Skip to content

4-1.对象的分类

Es6中的对象分类:

  1. 普通对象:具有 JavaScript 对象所有的默认内部行为。
  2. 特异对象:具有某些与默认行为不符的内部行为。
  3. 标准对象:ECMAScript6 规范中定义的对象,例如,ArrayDate 等。标准对象既可以是普通对象,也可以是特异对象。
  4. 内建对象:脚本开始执行时存在于 JavaScript 执行环境中的对象,所有标准对象都是内建对象。

4-2.对象字面量语法扩展

4-2-1.对象属性简写

js
var name = 'yxp'
var obj = {
  name
}

4-2-2.对象方法简写

js
var obj = {
  name: 'yxp',
  getName(name) {
    console.log(this.name)
  }
}

4-2-3.可计算属性名

js
var property = 'name'
var obj = {
  [property]: 'yxp'
}
console.log(obj)

4-3.重复的对象字面量属性

Es5 的严格模式中,对象字面量当中重复的同名属性,会抛出错误。

js
"use strict"
var person = {
  name: 'Tom',
  name: 'Jerry'
}

而在 Es6 当中,重复的对象字面量,会取值最后一位属性。

上例代码中, name 属性会取值 Jerry

4-4.自有属性枚举顺序

基本规则是:

  1. 所有数字键按照升序排序。
  2. 所有字符串键按照它们被加入对象的顺序排序。
  3. 所有 symbol 键按照它们被加入对象的顺序排序。

该规则主要影响 Object.getOwnPropertyNames() 方法及 Reflect.ownKeys 返回属性的方式。

Object.assign() 方法处理属性的顺序也将随之改变。

for...inObject.keys()JSON.stringify() 方法的枚举顺序则不确定,跟各大浏览器厂商的指定标准相关。

js
var obj = {
  a: 'a',
  2: '2',
  1: '1',
  c: 'c',
  b: 'b'
}
// Object.getOwnPropertyNames
var propertyNames = Object.getOwnPropertyNames(obj)
console.log(propertyNames) // ['1', '2', 'a', 'c', 'b']
// for...in
for (var k in obj) {
  console.log(k)
}
// Object.keys
var keys = Object.keys(obj)
console.log(keys)

4-5.简化原型访问的 Super 引用

  1. Super 引用相当于指向对象原型的指针。
js
var person = {
  getGreeting () {
    return 'hello'
  }
}
var dog = {
  getGreeting () {
    return 'woof'
  }
}
var friend = {
  getGreeting () {
    // Object.getPrototypeOf(this).getGreeting.call(this) 等于 super.getGreeting()
    return Object.getPrototypeOf(this).getGreeting.call(this) + ', friend'
  }
}
// friend的原型指向person
Object.setPrototypeOf(friend, person)
friend.getGreeting()
// friend的原型指向dog
Object.setPrototypeOf(friend, dog)
friend.getGreeting()
  1. 必须要在使用简写方法的对象中使用 Super 引用。
js
var person = {
  getGreeting () {
    return 'hello'
  }
}
var friend = {
  getGreeting: function () {
    return super.getGreeting() + ', hi'
  }
}
Object.setPrototypeOf(friend, person)
friend.getGreeting() // Uncaught SyntaxError: 'super' keyword unexpected here
  1. Super 处理多重继承,非常有用。因为 Super 引用不是动态化的,它总是指向正确的对象。
js
var person = {
  getGreeting () {
    return 'hello'
  }
}
var friend = {
  getGreeting () {
    // Object.getPrototypeOf(this).getGreeting.call(this) 出错,而 super.getGreeting() 会成功。
    // return Object.getPrototypeOf(this).getGreeting.call(this) + ', friend'
    return super.getGreeting() + ', friend'
  }
}
// friend的原型指向person
Object.setPrototypeOf(friend, person)
friend.getGreeting()
// 再创建一个对象 其原型指向friend
var relativer = Object.create(friend)
relativer.getGreeting()
// 由于this的指向问题,使用 Object.getPrototypeOf(this).getGreeting.call(this) 会报错:Uncaught RangeError: Maximum call stack size exceeded
// 使用 super.getGreeting() 会正常打印 'hello friend'

4-6.HomeObject

JavaScript 所有的函数都有一个名为 [[HomeObject]] 的属性。但并不是所有函数的该属性都有值。

js
// obj.getGreeting.[[HomeObject]] = obj
var obj = {
  getGreeting () {}
}
// Obj.prototype.getGreeting.[[HomeObject]] = Obj.prototype
class Obj {
  getGreeting () {}
}
// fn.[[HomeObject]] = undefined
function fn () {}

该属性在使用 super 的情况下特别有用。

当在函数内部调用 super 时,会先根据该函数的 [[HomeObject]] 定位到该函数的实际拥有者。

然后再利用 Object.getPrototypeOf() 定位到原型引用。

更多资料

4-7.新增方法

4-7-1.Object.is

看这里吧

4-7-2.Object.assign

看这里吧

4-7-3.Object.setPrototypeOf

看这里吧