面向物件(理解物件)——JavaScript基礎總結(一)
無序屬性的集合(散列表),其屬性可以包含基本值,物件或函式;
每個物件都是基於一個引用型別建立的,這個引用型別可以是原生型別,也可以是自定義型別。
建立物件
建立一個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]]
。
如有問題,歡迎指正。