话很少说直接上图!es6
// ES5
function person (name, age) {
return {
name: name,
age: age,
}
}
// ES6
function person (name, age) {
return {
name,
age,
}
}
复制代码
属性名表达式若是是一个对象,默认状况下会自动将对象转为字符串[object Object]。数组
属性名表达式与简洁表示法,不能同时使用,会报错。ide
let obj = {a: 1}
let only = 'id'
let person = {
[only]: 'key',
[obj]: 'this is obj', // 属性名表达式是一个对象
['na' + 'me']: 'doublemeng',
['get' + 'key'] () {
console.log(this[only]) // key
}
}
console.log(person) // {id: "key", [object Object]: "this is obj", name: "doublemeng", getkey: ƒ}
复制代码
ES5在严格模式下会去校验是否存在同名属性,存在则会报错。函数
ES6在严格模式、非严格模式下都不会去校验。post
'use strict'
let person = {
name: 'doublemeng',
name: 'Memory'
}
person.name // Memory
复制代码
对象的每一个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法能够获取该属性的描述对象。ui
let person = {
name: 'doublemeng'
}
Object.getOwnPropertyDescriptor(person, 'name')
// {value: "doublemeng", writable: true, enumerable: true, configurable: true}
复制代码
描述对象的enumerable属性,称为“可枚举性”,若是该属性为false,就表示某些操做会忽略当前属性。this
如下4个操做会忽略enumerable为false的属性:spa
- for...in循环:只遍历对象 自身的和继承的 可枚举的属性;
- Object.keys():返回对象 自身的 全部可枚举的属性的键名;
- JSON.stringify():只串行化对象 自身的 可枚举的属性;
- Object.assign(): 忽略enumerable为false的属性,只拷贝对象 自身的 可枚举的属性。
ES6 规定,全部 Class 的原型的方法都是不可枚举的。prototype
Object.getOwnPropertyDescriptor(
class {test() {}}.prototype,
'test'
).enumerable // false
复制代码
for...in
循环遍历对象 自身的和继承的 可枚举属性(不含Symbol
属性)。3d
Object.keys
返回一个数组,包括对象 自身的(不含继承的) 全部可枚举属性(不含Symbol
属性)的键名。
Object.getOwnPropertyNames
返回一个数组,包含对象 自身的 全部属性(不含 Symbol
属性,可是 包括不可枚举属性 )的键名。
Object.getOwnPropertySymbols
返回一个数组,包含对象 自身的 全部Symbol
属性的键名。
Reflect.ownKeys
返回一个数组,包含对象 自身的 全部键名,无论键名是 Symbol
或字符串,也无论是否可枚举。
以上方法遍历对象的键名,都遵照一样的属性遍历的次序规则:
- 首先遍历全部数值键,按照数值升序排列;
- 其次遍历全部字符串键,按照加入时间升序排列;
- 最后遍历全部 Symbol 键,按照加入时间升序排列。
let obj = {
name: 'doublemeng',
99: 99,
age: 18,
1: 1,
[Symbol('s2')]: 'this is s2',
2: 2,
[Symbol('s2')]: 'this is s1',
}
Reflect.ownKeys(obj) // ["1", "2", "99", "name", "age", Symbol(s2), Symbol(s2)]
复制代码
// ES5
var person = {
name: 'doublemeng',
sayName: function () {
console.log(this.name)
}
}
person.sayName() // doublemeng
// ES6
let person = {
name: 'doublemeng',
sayName () {
console.log(this.name)
}
}
person.sayName() // doublemeng
复制代码
返回函数名。
let person = {
sayName () {
console.log('name')
}
}
person.sayName.name // sayName
复制代码
特殊状况:
getter
&setter
的name属性不在该方法上面,在该方法的属性的描述对象的get
&set
属性上面,返回值是方法名前加上get
或set
。(这是在绕口令吗?绕不明白可参考面向对象(理解对象)——JavaScript基础总结(一) )
let person = {
get name() {},
set name (name) {}
};
// person.name.name // Cannot read property 'name' of undefined
let descriptor = Object.getOwnPropertyDescriptor(person, 'name')
descriptor.get.name // get name
descriptor.set.name // set name
复制代码
bind
方法创造的函数,返回bound
加上原函数的名字。
let person = {
sayName () {}
}
person.sayName.bind(null).name // bound sayName
复制代码
Function
构造函数创造的函数,返回anonymous
。
(new Function()).name // anonymous
复制代码
对象的方法是一个Symbol
值,返回该Symbol值的描述。
let fun = Symbol('Symbol value')
let obj = {
[fun] () {}
}
obj[fun].name // [Symbol value]
复制代码
指向当前对象的原型对象。
注意,
super
关键字表示原型对象时,只能用在对象的方法之中,用在其余地方都会报错。
目前,只有对象方法的简写法能够让
JavaScript
引擎确认,定义的是对象的方法。
JavaScript
引擎内部,super.foo
等同于Object.getPrototypeOf(this).foo
(属性)或Object.getPrototypeOf(this).foo.call(this)
(方法)。
let animal = {
name: 'animal',
sayName () {
console.log(this.name)
}
}
let dog = {
name: 'dog',
// super用在属性里面
// name: super.name, // embedded: 'super' outside of function or class
sayName () {
super.sayName()
},
// super用在一个函数里面1
// sayName: () => super.sayName // embedded: 'super' outside of function or class
// super用在一个函数里面2
// sayName: function () {return super.sayName()} // 'super' keyword unexpected here
}
Object.setPrototypeOf(dog, animal)
dog.sayName() // dog
复制代码
本文只要介绍了ES6中对于对象的属性和方法的一些扩展,以及super关键字的使用与注意事项。因为ES6对于对象新增内容较多,新增方法后续详细介绍。
其中涉及到对象的访问器属性
的内容稍稍有点多,若有不太明白的地方可参考面向对象(理解对象)——JavaScript基础总结(一)
感谢阅读,若有问题,欢迎指正。