1. 程式人生 > >JS面向物件之物件屬性的屬性

JS面向物件之物件屬性的屬性

ECMAScript的定義中,物件的屬性有兩種,一種是資料屬性,另一種是訪問器屬性

我們知道JS中有基本資料型別和物件,物件中的屬性也無外乎是這些型別,可是作為物件的屬性,這些屬性本身卻也多了一些特殊的屬性,而且屬性種類的不同也會使屬性的屬性有些許的差別。下面就來聊聊物件屬性的兩種類別。


1.資料屬性

這種屬性包含有一個存放資料值的屬性[[Value]],資料屬性共有4個描述其行為的屬性

  • [[Configurable]]:這個屬性表示能否用delete語句刪除屬性,能否修改屬性的屬性。預設為true。
  • [[Enumerable]]:這個屬性表示能否在使用for-in迴圈遍歷物件屬性時訪問到該物件。預設為true。
  • [[Writable]]:這個屬性表示能否修改屬性的值。預設為true。
  • [[Value]]:這個屬性用於存放屬性的資料值。

var course = {
    name: "Operation System"
}

在這個例子中我建立了一個course物件,這個物件有一個name屬性,name這個屬性的Configuralbe, Enumerable和Writable屬性都為true,而Value屬性則為"Operation System"。

若是想要修改屬性的屬性,則必須使用Object.defineProperty()方法。該方法接受三個引數,第一個是屬性所在物件,第二個是屬性的名字,第三個是描述符物件(descriptor).描述符物件的屬性只能是上述四種屬性,但不一定全部都要有。例如

Object.defineProperty(course, "name", {
    value: Assembler Language,
    writable: false
})

course.name = "English"
alert(course.name) //Assembler Language

我們把course的name屬性的writalbe屬性改成了false,將value屬性改為"Assembler Language",也就是說name屬性此時已經變為一個只讀屬性,所以當我們再次修改course的name屬性時會發現修改無效。(若是在嚴格模式下會導致錯誤) 

如果我們把name屬性的configurable屬性也改成false的話,則對屬性的所有屬性進行修改都會導致報錯(也不能把configurable改回true)

注:如果呼叫Object.defineProperty()方法來建立物件新屬性,如果不指定,那麼他的configuralbe, writable, enumerable屬性全為false。


2.訪問器屬性

訪問器屬性不包括資料的值,但它包含有getter和setter函式(並不必須,只指定getter意味著只讀,只指定setter意味只能寫入)。同資料屬性一樣,訪問器屬性也包含四個描述其行為的屬性。

  • [[Configurable]]:同上。
  • [[Enumerable]]:同上。
  • [[Get]]:在獲取屬性時呼叫的函式。
  • [[Set]]:在設定屬性時呼叫的函式。

注:訪問器屬性不能被直接定義,必須使用Object.defineProperty()方法


var person = {
    _age: 20
};

Object.defineProperty(person, "age", {
    get: function(){
        return this._age;
    },
    set: function(){
        this._age++;
    }
})

在這個例子中,我建立了一個person物件,裡面有一個_age屬性並賦值為20,然後我們又通過Object.defineProperty()為person新定義了一個age屬性,並定義了getter和setter函式。那麼在每次對person物件的age屬性進行修改時都會使_age自增。而在呼叫person.age時,也都返回的是person的_age屬性。