让前端飞技术干货

深入理解ES6 --- 对象

2019-03-29  本文已影响14人  漓漾li

对象字面量语法扩展

(1) 属性初始值简写

对象字面量属性赋值为同名的局部变量时,不必再写: 和值,只写属性名即可。这种写法不仅简洁,而且也有助于消除命名错误,

let name = '漓漾li'
let age = 18
// es5
let es5Info = {
    name: name,
    age: age,
}
// es6
let es6Info = {
    name,
    age,
}
(2) 对象方法简写

为对象字面量添加方法时,不用再写:function。两个函数唯一的区别就是简写函数可以使用super.

// es5
let es5Person = {
    sayName: function(){
        console.log('漓漾li')
    },
}
// es6
let es6Person = {
    sayName () {
        console.log('漓漾li')
    },
}
(3) 可计算属性名

es5中,如果一个对象的属性名称来源于变量或者计算结果,在初始化这个变量时,就必须使用[]代替.;es6中则可以直接在字面量中使用[]

let keyName = 'name'
// es5
let es5Info = {}
es5[keyName] = '漓漾li'

// es6
let es6Info = {
    [keyName]: '漓漾li'
}

字面量中使用[],表示属性名称是可计算的,所以中括号内可以使用表达式

新增方法

(1) Object.is()

引入Object.is()主要是为了弥补全等运算符===的一些不准确运算,其余的远算结果基本一致。

NaN === NaN  // false  应该是相等的
+0 === -0  // true   应该是不相等的

Object.is(NaN, NaN)   // true
Object.is(+0, -0)  // false
(2) Object.assign

概念不在赘述。

Object.assign不能将提供者的访问器属性复制到接受对象中

let obj = {
  get name(){
    return 'val'
  }
}
let a = Object.assign({}, obj)

Object.getOwnPropertyDescriptor(obj,'name').get   //  [Function: get name]
Object.getOwnPropertyDescriptor(a,'name').get   //   undefined
(3) Object.setPrototypeOf

Object.setPrototypeOf可以修改指定对象的原型

对象原型的存储在内部专用属性[Prototype]中,调用Object.getPrototypeOf可以返回其中的值,调用Object.setPrototypeOf可以改变其中的值

(4) super

super,指向当前对象的原型对象。
假设实例与原型中有同名的方法,想要调用原型中的同名方法,在es5中:

let person = {
  name: 'person',
  sayName(){
    return this.name
  }
}
let xiaoli = {
  name:'xiaoli',
  sayName(){
    // 调用原型中的同名方法,并自定义
    // 如果不自定义函数,那也就不需要在实例中重新定义这个函数
    return Object.getPrototypeOf(this).sayName.call(this) + ' hi'
  }
}
Object.setPrototypeOf(xiaoli, person)
console.log(xiaoli.sayName())   // xiaoli hi
  1. Object.getPrototypeOf(this)用来获取xiaoli的原型(即person);
  2. sayName.call(this)是为了让sayNamexiaoli的上下文中执行,如果不绑定this,则会输出person hi

而是用es6中的super,就可以实现上述两点:调用原型的同名方法;并绑定this到当前作用域

let person = {
  name: 'person',
  sayName(){
    return this.name
  }
}
let xiaoli = {
  name:'xiaoli',
  sayName(){
    return super.sayName() + ' hi'
  }
}
Object.setPrototypeOf(xiaoli, person)
console.log(xiaoli.sayName())  // xiaoli hi

super必须在简写方法的对象中使用,否则会语法错误

对象属性的遍历

  • 对象的每一个属性都会有一个描述对象,来控制这个属性的行为。Object.getOwnPropertyDescriptor可以获取到对象属性的描述对象。
  • 描述对象中的enumerable属性,称为可枚举性如果enumerablefalse,则某些对象属性遍历的操作,就会忽略该属性
  • enumerable属性引入的目的就是让一些内部属性和方法避免被遍历到。比如对象原型的toString方法,和数组的length属性
方法\是否能遍历特殊属性 不可枚举属性 继承的可枚举属性 Symbol属性 备注
for...in 大多情况只关心对象自身的属性,谨慎使用
Object.keys(obj)
Object.getOwnPropertyNames(obj)
Object.getOwnPropertySymbols(obj) 只返回symbol属性
Reflect.ownKeys(obj)

遍历顺序规则:

  1. 首先遍历所有数值键,按照数值升序排列;
  2. 其次遍历所有字符串键,按照加入时间升序排列;
  3. 最后遍历所有 Symbol 键,按照加入时间升序排列。
上一篇下一篇

猜你喜欢

热点阅读