【面向對象的程序設計(1)】屬性

屬性類型

數據屬性

數據屬性包含一個數據值的位置。在這個位置可以讀取和寫入值。

共有4個描述其行為的特性。

  • [[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。對于直接在對象上定義的屬性,默認為true。
  • [[Enumerabel]]:表示能否通過for-in循環返回屬性。對于直接在對象上定義的屬性,默認為true。
  • [[Writable]]:表示能否修改屬性的值。對于直接在對象上定義的屬性,默認為true。
  • [[Value]]:包含這個屬性的數據值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。默認為undefined。

修改屬性默認的特性,使用ECMAScript 5中的Object.defineProperty()方法。

/* Object.defineProperty()
 * param:
 *       param1——屬性所在的對象
 *       param2——屬性的名字
 *       param3——一個描述符對象(描述符對象的屬性必須是:
 *               Configurable、Enumerabel、Writable、Value)
 */
 var person = {};
 Object.defineProperty(person,"name",{
     writable:false,
     value:"Nicholas"
 });
 console.log(person.name);  //Nicholas
 person.name = "Greg";
 console.log(person.name);  //Nicholas

調用Object.defineProperty()方法創建一個新的屬性時,如果不指定,Configurable、Enumerabel、Writable特性的默認值都是false,如果調用Object.defineProperty()只是修改已定義的屬性的特性,則無此限制。

訪問器屬性

包含一對getter和setter函數(都不是必須的)。
在讀取訪問器屬性時,會調用getter函數,返回有效的值;在寫入訪問器屬性時,會調用setter函數,傳入新值。

訪問器屬性有如下4個特性:

  • [[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性。對于直接在對象上定義的屬性,默認為true。
  • [[Enumerabel]]:表示能否通過for-in循環返回屬性。對于直接在對象上定義的屬性,默認為true。
  • [[Get]]:在讀取屬性時調用的函數。默認為undefined。
  • [[Set]]:在寫入屬性時調用的函數。默認為undefined。

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

var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book, "year", {
    get: function () {
        return this._year;
    }, set: function (newValue) {
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book._year=2005;
console.log(book.edition); //2

只有getter意味著屬性不能寫,嘗試寫入屬性會被忽略,嚴格模式下,嘗試寫入只有getter函數的屬性會拋出錯誤。
只有setter意味著屬性不能度,嘗試讀會返回undefined,嚴格模式下會拋出錯誤。

定義多個屬性

/* Object.defineProperties()
 * 可以通過描述符一次定義多個屬性。
 * param:接收兩個對象參數
 *      param1——要添加和修改其屬性的對象
 *      param2——其屬性與第一個對象中要添加或修改的屬性一一對應
 */
 
var book = { };
Object.defineProperties(book,{
   _year:{
       writable:true,
       value:2004
   },
   edition:{
       writable:true,
       value:1
   },
   year:{
       get:function(){
           return this._year;
       },
       set:function(newValue){
           if (newValue > 2004) {
               this._year = newValue;
               this.edition += newValue - 2004;
           }
       }
   }

讀取屬性的特性

/* Object.getOwnPropertyDescriptor()
 * 取得給定屬性的描述符。
 * param:
 *       param1——屬性所在的對象
 *       param2——要讀取其描述符的屬性名稱
 * return:返回值是一個對象
 *       如果是訪問器屬性,則此對象的屬性有configurable、enumerable、
 *       get和set;
 *       如果是數據屬性,則此對象的屬性有configurable、enumerable、
 *       writable和value。
 */

var book = {};
Object.defineProperties(book, {
    _year: {
        writable: true,
        value: 2004
    },
    edition: {
        writable: true,
        value: 1
    },
    year: {
        get: function () {
            return this._year;
        },
        set: function (newValue) {
            if (newValue > 2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    }
});
var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
console.log(descriptor.value);           //2004
console.log(descriptor.configurable);    //false
console.log(typeof  descriptor.get);     //undefined

var decriptor = Object.getOwnPropertyDescriptor(book,"year");
console.log(decriptor.value);            //undefined
console.log(decriptor.enumerable);       //false
console.log(typeof  decriptor.get);      //function

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容