定義
無序屬性的集合(雜湊表),其屬性可以包含基本值,物件或函式;
每個物件都是基於一個引用型別建立的,這個引用型別可以是原生型別,也可以是自定義型別。
建立物件
建立一個Object例項
var person = new Object()
person.name = 'Memory'
person.age = 24
person.sayName = function () {
console.log(this.name) // Memory
}
複製程式碼
物件字面量
var person = {
name: 'Memory',
age: 24,
sayName: function () {
console.log(this.name) // Memory
}
}
複製程式碼
其中name
和age
是person的屬性,sayName
是person的方法。
屬性型別
只有內部才用的特性,在JS中不能直接訪問它們,為了表示特性是內部值,把它們放到了[[]]中;
ECMAScript中有以下兩種屬性,資料屬性和訪問器屬性。
資料屬性
其中,person.name的[Configurable]]、[[Enumerable]]、[[Writable]]都為true,[[Value]]為Memory。
修改資料屬性:Object.defineProperty(物件obj
, [屬性名稱]
, 描述符物件
)
其中,描述符物件的屬性必須是configurable、enumerable、writable、value之內的一到四個。
在呼叫Object.defineProperty時,如果不指定,configurable、enumerable、writable的值都預設為false
;
在把configurable設為false之前,可以多次呼叫Object.defineProperty()修改同一個屬性。之後修改除writable
之外的其他特性,都會導致錯誤;
嘗試修改writable:
Object.defineProperty(person, 'name', {
configurable: false,
})
console.log(person.name) // Memory
Object.defineProperty(person, 'name', {
writable: true,
value: 'doublemeng'
})
console.log(person.name) // doublemeng
複製程式碼
嘗試修改configurable:
Object.defineProperty(person, 'name', {
configurable: false,
})
console.log(person.name) // Memory
// Uncaught TypeError: Cannot redefine property: name
Object.defineProperty(person, 'name', {
configurable: true,
value: 'doublemeng'
})
console.log(person.name)
複製程式碼
configurable設為false,即表示不能從物件中刪除屬性;
如果這個物件呼叫delete,非嚴格模式下會被忽略,嚴格模式下則會拋錯。
writable設為false,即表示該屬性不可寫;
非嚴格模式下會被忽略,嚴格模式下則會拋錯。
訪問器屬性
訪問器屬性包含getter和setter函式(這兩個函式都不是必需的),其中setter用來寫值,getter用來讀值。
設定一個屬性的值會導致其他屬性的變化,如下例year
的變化導致_year
和age
的變化:
var book = {
age: 1,
_year: 2000 // 只能通過物件方法訪問的屬性
}
console.log(book._year) // 2000
console.log(book.age) // 1
Object.defineProperty(book, 'year', {
get: function () {
return this._year
},
set: function (newYear) {
this._year = newYear
this.age = newYear - 2000 + 1
}
})
book.year = 2019
console.log(book._year) // 2019
console.log(book.age) // 20
複製程式碼
不一定非要指定getter和setter;
只指定getter意味著屬性只能讀不能寫;
嘗試寫入,在非嚴格模式下會被忽略,嚴格模式下則會拋錯。
只指定setter意味著屬性只能讀不能讀;
嘗試讀取,在非嚴格模式下會返回undefined,嚴格模式下則會拋錯。
在該方法之前,要建立訪問器屬性一般要使用兩個非標準的方法:__defineGetter__()
和 __defineSetter__()
var book = {
age: 1,
_year: 2000 // 只能通過物件方法訪問的屬性
}
console.log(book._year) // 2000
console.log(book.age) // 1
book.__defineGetter__('year', function () {
return this._year
})
book.__defineSetter__('year', function (newYear) {
this._year = newYear
this.age = newYear - 2000 + 1
})
book.year = 2019
console.log(book._year) // 2019
console.log(book.age) // 20
複製程式碼
不支援Object.defineProperty()
的瀏覽器不能修改[Configurable]]
和[[Enumerable]]
定義多個屬性
Object.defineProperties(物件obj
,物件 其屬性為obj要新增和修改的屬性
)
讀取屬性的特性
Object.getOwnPropertyDescriptor(物件
,屬性
)
參考
《JavaScript高階程式設計》
小結
本文主要介紹了物件屬性的各種特性。其主要包括資料屬性的[[Configurable]]
、[[Enumerable]]
、[[Writable]]
、[[Value]]
和訪問器屬性的[[Configurable]]
、[[Enumerable]]
、[[Get]]
、[[Set]]
。
如有問題,歡迎指正。