話很少說直接上圖!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基礎總結(一)
感謝閱讀,若有問題,歡迎指正。