友情鏈接:
內容要點:
一.對象屬性
對象屬性是由名字、值和一組特性構成的。在ES5中,屬性值可以用一個或兩個方法替代,這兩個方法就是getter和setter。由getter和setter定義的屬性稱做 "存儲器屬性",它不同於 "數據屬性",數據屬性就是一個簡單的值。
當程序查詢存取器屬性的值時,JS調用getter方法(無參數)。這個方法的返回值就是屬性存取表達式的值。
當程序設置一個存取器屬性的值時,JS調用setter方法,將賦值表達式右側的值當做參數傳入setter。從某種意義上講,這個方法負責 "設置"屬性值。可以忽略setter方法的返回值。
和數據屬性不同,存取器屬性不具有可寫性。如果屬性同時具有getter和setter,那么它是一個讀/寫屬性。如果它只有getter方法,那么它是一個只讀屬性。如果它只有setter方法,那么它是一個只寫屬性(數據屬性中有一些例外),讀取只寫屬性總是返回undefined.
二.定義存取器屬性
定義存取器屬性最簡單的方法是使用對象直接量語法的一種擴展寫法:
var o = {
//普通的數據屬性
data_prop : value,
//存取器屬性都是成對定義的函數
get accessor_prop() {/*這里是函數體*/},
set accessor_prop() {/*這里是函數體*/}
};
存取器屬性定義為一個或兩個和屬性同名的函數,這個函數定義沒有使用function關鍵字,而是使用get和(或)set.
注意,這里沒有使用冒號將屬性名和函數體分隔開,但在函數體的結束和下一個方法或數據屬性之間有逗號分隔。
例如:
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); }
};
三.存取器屬性是可以繼承的
和數據屬性一樣,存取器屬性是可以繼承的,因此可以將上述代碼中的對象p當做另一個 "點" 原型。可以給新對象定義它的x和y屬性,但r和theta屬性是可以繼承的:
var q = inherit(p); //創建一個繼承getter和setter的新對象
q.x=1,q.y=1; //給q添加兩個屬性
console.log(q.r); //可以使用繼承的存取器屬性
console.log(q.theta);
四.
//這個對象產生嚴格自增的序列號
var serialnum = {
//這個數據屬性包含下一個序列號
//$符號暗示這個屬性是一個私有屬性
$n : 0 ,
//返回當前值,然后自增
get next(){ return this.$n++ },
set next(n){
if(n >= this.$n) this.$n = n;
else throw "序列號的直不能比當前值小"
}
};
//下面這個例子使用getter方法實現一種"神奇"的屬性
//這個對象有一個可以返回隨機數的存取器屬性
//例如,表達式 "random.octet"產生一個隨機數
//每次產生的隨機數都在0-255之間
var random = {
get octet(){ return Math.floor(Math.random()*256); },
get uint16(){ return Math.floor(Math.random()*65536); },
get init16(){ return Math.floor(Math.random()*65536)-32768; }
};
