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