0×00背景
我們知道物件導向的語言有一個標誌就是有類的概念,通過類可以建立多個具有相同屬性和方法的對象。但是ECMAScript中沒有類的概念,所以它的對象和其他基於類的語言中的對象有點不同,它是基於原型的物件導向。ECMA-262把對象定義為“無序屬性的集合,其屬性可以包含基本值,對象或者函數”。每個對象都是基於一個參考型別建立的,這個參考型別可以是原生的參考型別,也可以是自訂的類型。
我們先用最簡單的方式建立一個對象
| 代碼如下 |
複製代碼 |
|
var person = new Object();
person.name = “gothic”;
person.age = 21;
person.job = “f2e”;
person.sayName = function(){
alert(this.name);
}; |
這個對象裡我們添加了三個屬性(name,age,job)和一個方法(sayName())。當然我們也可以用對象字面量來重寫這個對象:
| 代碼如下 |
複製代碼 |
|
var person = {
name:”gothic”,
age:21,
job:”f2e”,
sayName:function(){
alert(this.name);
}
}
|
0×01屬相類型
ECMAScript有兩種屬性:資料屬性和訪問器屬性
1.資料屬性
資料屬性包含一個資料值的位置,在這個位置可以讀取和寫入值。它有四個特性:
Configurable:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,預設值是true.
Enumerable:表示能否通過for-in迴圈返回屬性。像上面第一個例子那樣直接在對象上定義屬性,預設值為true.
Writable:表示能否修改屬性的值。預設值為true.
Value:包含這個屬性的資料值,讀取屬性的時候,從這個位置讀,寫入屬性的時候,把新值儲存在這個位置。預設值為:undefined.
如果要修改屬性預設的特性,必須要使用Object.defineProperty()方法。這個方法接受三個參數:屬性所在的對象、屬性的名字、一個描述符對象。其中描述符對象的屬性必須是configurable,enumerable,writable,value.通過設定其中的一個或多個值,可以修改對應的特性值,如下:
| 代碼如下 |
複製代碼 |
|
var person={};
Object.defineProperty(person,”name”,{
writable:false,
value:”gothic”
}); www.111cn.net
alert(person.name);//”gothic”
person.name=”dyy”;
alert(person.name);//”gothic” |
這裡我們也可以把writable:false,換為configurable:false,表示不能從對象裡刪除屬性,也就是說如果這是對這個屬性調用delete則在非strict 模式下不會發生什麼,但是在strict 模式下會發發生錯誤。
而且這是如果再想用Object.defineProperty()方法修改除上面那個writable之外的屬性則會發生錯誤,因為Object.defineProperty()可以多出被調用修改同一個屬性,但是在把configruable設定為false之後就會有限制了。
一般情況下在調用Object.defineProperty()時,如果不指定,幾個特性的預設值都為false。
0×02訪問器屬性
訪問器屬性有以下四個特性:
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.year = 2005;
alert(book.edition); //2 |
上面代碼訪問器屬性year包含一個getter函數和setter函數,這裡這個_year前面那個底線是一種常用的記號,用於表示只能通過對象方法訪問的是屬性,getter函數返回_year的值,setter函數通過計算來確定正確的版本。當然有的時候我們不一定非要同時指定getter和setter,只指定getter表示屬性不能寫,而指給定setter表示屬性不能讀,否則在非strict 模式下會返回undefined,在strict 模式下會出錯。
2定義多個屬性
利用Object.defineProperties()方法來一次定義多個屬性。這個方法接受兩個對象參數:一個對象是要添加和修改其屬性的對象;第二個對象的屬性與第一個對象中要添加或修改的屬性一一對應。如下:
| 代碼如下 |
複製代碼 |
|
var book = {};
Object,defineProperties(book,{_year:{
value:2004
},
edition:{value:1},
year:{
get:function(){
return this._year;
}, www.111cn.Net
set:function(newValue){
if (newValue>2004){
this._year = newValue;
this.edition+=newVAlue-2004;
}
}
}
}); |
3讀取屬性的特性
使用Object.getOwnPropertyDescriptor()方法可以取得給定屬性的描述符。這個方法接受兩個參數:屬性所在的對象和要讀取其描述符的屬性名稱。如果擷取的是訪問器屬性,這個對象的值有:configurable,enumerable,get和set,如果是資料屬性,這個對象的屬性有:configurable,enumerable,writable,value。