深入理解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
Object.getPrototypeOf(this)
用来获取xiaoli
的原型(即person
);sayName.call(this)
是为了让sayName
在xiaoli
的上下文中执行,如果不绑定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
属性,称为可枚举性,如果enumerable
为false
,则某些对象属性遍历的操作,就会忽略该属性。enumerable
属性引入的目的就是让一些内部属性和方法避免被遍历到。比如对象原型的toString
方法,和数组的length
属性
方法\是否能遍历特殊属性 | 不可枚举属性 | 继承的可枚举属性 | Symbol属性 | 备注 |
---|---|---|---|---|
for...in |
✘ | ✔ | ✘ | 大多情况只关心对象自身的属性,谨慎使用 |
Object.keys(obj) |
✘ | ✘ | ✘ | |
Object.getOwnPropertyNames(obj) |
✔ | ✘ | ✘ | |
Object.getOwnPropertySymbols(obj) |
✔ | ✘ | ✔ | 只返回symbol 属性 |
Reflect.ownKeys(obj) |
✔ | ✘ | ✔ |
遍历顺序规则:
- 首先遍历所有数值键,按照数值升序排列;
- 其次遍历所有字符串键,按照加入时间升序排列;
- 最后遍历所有 Symbol 键,按照加入时间升序排列。