javaScript對象的屬性是由名字、值和一組特性組成的。在ECMAScript5中,屬性的值可以由一個或兩個方法替代,這兩個方法就是getter和setter。由getter和setter定義的屬性稱為“存取器屬性”,它不同于“數(shù)據(jù)屬性”,數(shù)據(jù)屬性只有一個簡單的值。
當(dāng)程序查詢存取器屬性的值時,Javascript調(diào)用getter方法(無參數(shù))。這個方法返回的值就是屬性存取表達(dá)式的值。當(dāng)程序設(shè)置一個存取器屬性的值時,JavaScript調(diào)用setter方法,將賦值表達(dá)式右側(cè)的值當(dāng)做參數(shù)傳入setter。從某種意義上講,這個方法負(fù)責(zé)“設(shè)置”屬性值。可以忽略setter方法的返回值。
和數(shù)據(jù)屬性不同,存取器屬性不具有可寫性。如果屬性同時具有g(shù)etter和setter方法,那么它是一個讀/寫屬性。如果它只有g(shù)etter方法,那么它是一個只讀屬性。如果它只有setter方法,那么它是一個只寫屬性(數(shù)據(jù)屬性中有一些例外),讀取只寫屬性總是返回undefined。
定義存取器屬性最簡單的一種方法是使用對象直接量語法的一種擴(kuò)展寫法:
var o = { //普通的數(shù)據(jù)屬性 data_PRop: value, //存取器屬性都是成對定義的函數(shù) get accessor_prop(){/*這里是函數(shù)體*/}, set accessor_prop(value){/*這里是函數(shù)體*/}};存取器屬性定義為一個或兩個和屬性同名的函數(shù),這個函數(shù)定義沒有使用function關(guān)鍵字,而是使用get和set。注意這里沒有使用冒號將屬性名和函數(shù)體分開,但在函數(shù)體的結(jié)束和下一個方法或數(shù)據(jù)屬性之間有逗號分隔。例如,思考下面這個表示2D笛卡爾點(diǎn)坐標(biāo)的對象,它有兩個普通的屬性x和y分別表示對應(yīng)點(diǎn)的X坐標(biāo)和Y坐標(biāo),它還有兩個等價的存取器屬性用來表示點(diǎn)的極坐標(biāo):var p = { //x和y是普通的可讀寫的數(shù)據(jù)屬性 x: 1.0, y: 1.0, //r是可讀寫的存取器屬性,它有g(shù)etter和setter。 //函數(shù)體結(jié)束之后不要忘記帶上逗號 get r(){ return Math.sqrt(this.x * this.x + this.y * this.y); }, set r(newValue){ var oldValue = Math.sqrt(this.x * this.x + this.y * this.y); var ratio = newValue / oldValue; this.x *= ratio; this.y *= ratio; }, //theta是只讀存取器屬性,它只有g(shù)etter方法 get theta(){ return Math.atan2(this.y, this.x);}};注意這段代碼里面getter和setter使用了this關(guān)鍵字。在函數(shù)體內(nèi)的this指向表示這個點(diǎn)的對象,因此r屬性的getter方法可以通過this.x和this.y來引用x屬性和y屬性。
和數(shù)據(jù)屬性一樣,存取器屬性是可以繼承的。因此可以將上述代碼中的對象p當(dāng)做另一個點(diǎn)的原型。
在ECMAScript5標(biāo)準(zhǔn)被采納之前,大多數(shù)JavaScript的實(shí)現(xiàn)已經(jīng)可以支持對象直接量語法中的get和set寫法。這些實(shí)現(xiàn)提供了非標(biāo)準(zhǔn)的老式API用來查詢和設(shè)置getter和setter。這些API由4個方法組成,所有對象都擁有這些方法。__lookupGetter__()和__lookupSetter__()用以返回一個命名屬性的getter和setter方法。__defineGetter__()和__defineSetter__()用以定義getter和setter,這兩個函數(shù)的第一個參數(shù)是屬性名字,第二個參數(shù)是getter和setter方法。這4個方法都是以兩條下劃線作為前綴,兩條下劃線作為后綴,以表明它們是非標(biāo)準(zhǔn)的方法。
新聞熱點(diǎn)
疑難解答
圖片精選