Js高級之面向對象的程序設計

一、理解對象

ECMA-262定義對象爲:無序屬性的集合,屬性可包含基本值、對象和函數。

通俗來講,對象是一組名值對,類似於散列表。

二、對象的屬性類型

1.屬性類型特性

對象由一組屬性名和屬性值組成,則必然存在屬性的增刪改查。

對象的屬性類型分爲數據屬性和訪問器屬性,爲了定義其只有內部才能使用的特性,採用[[  ]]表示。

數據屬性:即控制屬性的增刪改查的行爲的設置

  • [[Configurable]]:能否通過delete刪除屬性進行重新定義或能否修改屬性特性或修改爲訪問器屬性。默認爲true
  • [[Enumerable]]:能否通過for-in循環返回屬性。默認true
  • [[Writable]]:能否修改屬性值。默認爲true
  • [[Value]]:該屬性的數據值。默認爲undefined
var person={};

Object.defineProperty(person,'name',{
    configurable:false,
    value:'Ermiao'
});

alert(person.name);//輸出"Ermiao"
delete person.name
alert(person.name);//仍輸出"Ermiao",因爲配置不可刪除

//拋出錯誤,一旦設置爲false,則不可以變回true
Object.defineProperty(person,'name',{
    configurable:true,
    value:'Ermiao'
});

訪問器屬性:即監聽屬性的增刪改查行爲的過程

  • [[Configurable]]:能否通過delete刪除屬性進行重新定義或能否修改屬性特性或修改爲訪問器屬性。默認爲true
  • [[Enumerable]]:能否通過for-in循環返回屬性。默認true
  • [[Get]]:讀取屬性時調用的函數。默認undefined(若只有get函數沒有set函數,意味着只讀)
  • [[Set]]:寫入屬性時調用的函數。默認undefined(若只有set函數沒有get函數,意味着只寫)
  • [[Get]]和[[Set]]的非標準方法:

        對象名 . __defineGetter__(屬性名,function(){ ... })

        對象名 . __defineSetter__(屬性名,function(){ ... })

var book={
    _year:2019,  //屬性名前加_表示只能通過對象方法訪問的屬性
    edition:1
};

Object.defineProperty(book,"year",{
    get:function(){
        return this._year;
    },
    set:function(newValue){
        if (newValue>2019){
            this._year = newValue;
            this.edition += newValue-2019;
        }
    }
});

book.year = 2020;  // year是訪問器屬性,_year是數據屬性
alert(book.edition) //輸出2

注意:一旦將屬性定義爲不可配置就無法變回可配置!!!

2.定義屬性類型特性的方法:

  • 定義或修改一個屬性的特性:Object.defineProperty(對象名,屬性名,描述符對象)

       在適應該方法定義一個新的數據屬性時,若不指定,則Configurable、Enumerable和Writable默認爲false。

  • 定義或修改多個屬性的特性:Object.defineProperties(對象名,{屬性名1,描述符對象1,...  ,屬性名n,描述符對象n})
  • 讀取一個屬性的特性:Object.getOnePropertyDescriptor(對象名,屬性名)

        該方法返回值爲一個描述符對象

var book={};

Object.defineProperties(book,{  //定義多個屬性特性
    _year:{
      value:2019  
    },
    edition:{
      value:1
    },
    year:{
        get:function(){
            return this._year;
        },
        set:function(newValue){
            if (newValue>2019){
                this._year = newValue;
                this.edition += newValue-2019;
            }
        }
    }

});

var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
alert(descriptor.configurable) // 輸出false
alert(descriptor.value) // 輸出2019
alert(typeof descriptor.get) // 輸出undefined,因爲_year是數據屬性,沒有get特性

var descriptor = Object.getOwnPropertyDescriptor(book,"year");
alert(descriptor.enumerable) // 輸出false
alert(descriptor.value) // 輸出undefined,因爲year是訪問器屬性,沒有value特性
alert(typeof descriptor.get) // 輸出function,

三、創建對象

JavaScript中創建對象的方法有7種,具體內容請看:js基礎之創建對象的7種方法

四、繼承

(未完)

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章