標籤:描述符 調用 存在 資料 ret java attr setter 規範
ECMA-262第5版在定義只有內部才用的特性(attribute)時,描述了屬性(property)的各種特性。ECMA-262定義這些特性是為了實現javascript引擎用的,因此在javascript中不能直接存取它們。為了表示特性是內部值,該規範把它們放在了兩對方括弧中,例如[[Enumerable]]。
ECMAScript中有兩種屬性:資料屬性和訪問器屬性。
1、資料屬性包含一個資料值的位置。在這個位置可以讀取和寫入值。資料屬性有4個描述其行為的特性。
[[Configurable]]: 表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。直接在對象上定義的 屬性,它們的這個特性預設值為true。
[[Enumerable]]:表示能否通過for-in迴圈返回屬性。直接在對象上定義的屬性,它們的這個特性預設值為true。
[[Writable]]:表示能否修改屬性的值。直接在對象上定義的屬性,它們的這個特性預設值為true。
[[Value]]:包含著歌屬性的資料值。讀取屬性值的時候,從這個位置讀;寫入屬性的時候,把新值儲存在這個位置。這個特性的預設值為undefined。
例如:
var person = {name:"zcybb"};
像這樣直接在對象上定義的屬性,它們的[[Configurable]],[[Enumerable]],[[Writable]]特性都被設定為true,而[[Value]]特性被設定為指定的值。
要修改屬性預設的特性,必須使用ECMAScript 5的Object.defineProperty()方法。這個方法接收三個參數:屬性所在的對象,屬性的名字和一個描述符對象,設定其中的一或多個值,可以修改對應的特性值。
例如:
var person = {};
Object.defineProperty(person,"name",{
writable:false,
value:"bbzcy"
});
這個例子建立了一個名為name的屬性,它的"bbzcy"是唯讀,這個屬性的值是不可修改的,如果嘗試為它指定新值,在非strict 模式下,賦值操作將被忽略,在strict 模式下,賦值操作將會導致拋出錯誤。
把configurable設定為false,表示不能從對象中刪除屬性。而且一旦把屬性定義為不可配置的,就不能再把它變回可配置的了,此時再調用Object.defineProperty()方法修改除了writable之外的特性,都會導致錯誤。
也就是說,可以多次調用Object.defineProperty()方法修改同一個屬性,但在把 configurable特性設定為false之後就會有限制了。
在調用Object.defineProperty()方法建立一個新的屬性時,如果不指定,configurable,enumerable和writable特性的預設值都是false。
2、訪問器屬性
訪問器屬性不包含資料值;它們包含一對getter和setter函數(不過這兩個函數都不是必需的)。在讀取存取器屬性時會調用getter函數,這個函數負責返回有效值;在寫入訪問器屬性時,會調用setter函數,並傳入新值,這個函數負責決定如何處理資料。訪問器屬性有如下4個特性。
[[Configurable]]: 表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為資料屬性。直接在對象上定義的屬性,它們的這個特性預設值為true。
[[Enumerable]]:表示能否通過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.__defineGetter__("year",function(){
return this._year;
});
book.__defineSetter__("year",function(newValue){
if(newValue > 2004){
this._year = newValue;
this.edition +=newValue-2004;
}
});
定義多個屬性:
var book = {};
Object.defineProperty(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;
}
}
}
}
)
javascript中的屬性類型