在javaScript中,對象的屬性分為兩種類型:數據屬性和訪問器屬性。
一、數據屬性
數據屬性:包含一個數據值的位置,在這個位置可以讀取和寫入值。數據屬性有4個描述其行為的特性:
1、value:包含該屬性的數據值,默認為undefined。
2、writable:表示能否修改屬性的值。
3、enumerable:表示能否通過for-in循環返回屬性。
4、configurable:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問器屬性,默認為true。
如下面這個例子:創建一個對象person,打印出name屬性的特性的默認值。
執行結果:
修改數據屬性的默認特性:
修改數據屬性的默認特性要用到一個方法:Object.defineProperty()方法,這個方法有三個參數:屬性所在的對象,屬性名,一個描述符對象。
Object.defineProperty(person,'name',{ writable:false, value:"aaa", configurable:false, enumerable:false })
二、訪問器屬性
1、訪問器屬性:這個屬性不包含數據值,包含一對get和set方法,在讀寫訪問器屬性時,就是通過這兩個方法來進行操作處理的。
2、訪問器屬性包含四個特性:
configurable:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問器屬性,默認為false。
enumerable:表示能否通過for-in循環返回屬性,默認為false。
Get:在讀取屬性時調用的函數,默認為undefined。
Set:在寫入屬性時調用的函數,默認為undefined。
注意:訪問器屬性不能直接定義,要通過Object.defineProperty()這個方法來定義。
var book = { _year:2020,//下划線表示內部屬性,只能通過對象的方法來讀寫 editor:2 } console.log(book) Object.defineProperty(book,'year',{ get(){ return this._year }, //若只指定get不指定set,那就默認該屬性是只讀的。 set(newYear){ if(newYear !== this._year){ this._year = newYear; this.editor++; } } }) console.log(Object.getOwnPropertyDescriptor(book,'year')); console.log("未修改"+book.year); book.year = 2018; console.log('修改后year的值'+book.year); console.log('修改year的值后,editor屬性的值:'+book.editor);
執行結果:
拓展:
1、Object.defineProperty()
通過Object.defineProperty() 可以直接在對象上創建一個屬性,也可以修改已有的屬性。
Object.defineProperty(obj, prop, descriptor) 接收三個參數:
obj:屬性所在的對象
prop:要訪問的屬性名
descriptor:描述符對象
描述符對象包含六個屬性:configurable、enumerable、writable、value、get、set ,要修改屬性的特性,必須使用Object.defineProperty()方法。
通過以上兩種方式添加的對象屬性,其布爾值特性默認值是true,通過Object.defineProperty來修改屬性特性時,只設置需要修改的特性即可;而通過Object.defineProperty創建的屬性,其布爾值特性默認值是false。
2、Object.defineProperties()
通過Object.defineProperties()可以一次性為對象定義多個屬性。
var person = {}; Object.defineProperties(person, { name: { value: 'Nicy', writable: true }, _age: { value: 21, enumerable: true, writable: true, configurable: true }, age: { get: function() { return this._age; }, set: function(value) { this._age = value; } } });