面向對象的一個標誌是它們都有類的概念,而JavaScript中沒有類的概念,因此它的對象與其他語言基於類的對象定義不同。 理解對象 前面介紹過對象的兩種創建方式:構造函數和對象字面量: var p = new Object(); p.name = "蕭蕭弈寒"; p.blog = "cnblogs. ...
面向對象的一個標誌是它們都有類的概念,而JavaScript中沒有類的概念,因此它的對象與其他語言基於類的對象定義不同。
理解對象
前面介紹過對象的兩種創建方式:構造函數和對象字面量:
var p = new Object();
p.name = "蕭蕭弈寒";
p.blog = "cnblogs.com";
p.sayName = function() {
alert(this.name);
}
var person = {
name : "蕭蕭弈寒",
blog : "cnblogs.com",
sayName : function() {
alert(this.name);
}
}
1.屬性類型
JavaScript中有兩種屬性:數據屬性和訪問器屬性。
1.1數據屬性
數據屬性包括一個數據值的位置。在這個位置可以讀取和寫入值。數據屬性有4個特性:
- [[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性特性,或者能否把屬性修改為訪問器屬性。
- [[Enumerable]]:表示能否通過for-in迴圈返回屬性。
- [[Writable]]:表示能否修改屬性的值。
- [[Value]]:包含屬性的值。讀取屬性值的時候,從這個位置讀,寫入屬性值的時在這個位置寫入新值。預設值為undefined。
JavaScript的Object.defineProperty()方法要修改預設屬性的特性。這個方法接收三個參數:屬性所在的對象、屬性名和一個描述符對象。其中描述符對象必須是:configurable、enumerable、writable和value。設置其中的一或多個值,可以修改對應的特性值。
var person = {};
Object.defineProperty(person, "name", {
writable : false,
value : "cnblogs"
});
alert(person.name); // "cnblogs"
person.name = "xxyh";
alert(person.name); // "cnblogs"
類似的規則也適用於不可配置的屬性。例如:
var person = {};
Object.defineProperty(person, "name", {
congigurable : false,
value : "cnblogs"
});
alert(person.name); // "cnblogs"
delete person.name;
alert(person.name); // "cnblogs"
把configurable設置為false,表示不能從對象中刪除屬性。一旦把屬性定義為不可配置的,則不能再將其設置為可配置的。如果在調用Object.defineProperty()方法修改除了writable之外的特性都會出錯。
var person = {};
Object.defineProperty(person, "name", {
configurable : false,
value : "xxyh"
});
Object.defineProperty(person, "name", {
configurable : true, // 出錯
value : "xxyh"
});
1.2訪問器屬性
訪問器屬性不包含數據值;它們包含一對getter和setter函數(不是必需的),用於訪問器屬性的讀寫。訪問器屬性有四個特性:
- [[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性。預設值為true。
- [[Enumerable]]:表示能否通過for-in迴圈返回屬性。
- [[Get]]:在讀取屬性時調用函數。預設值為undefined
- [[Set]]:在寫入屬性時調用函數。預設值為undefined
訪問器屬性不能直接定義,必須使用Object.defineProperty()定義。
var book = {
_year : 2015,
edition : 1
};
Object.defineProperty(book, "year", {
get : function() {
return this._year;
},
set : function(newValue) {
if (newValue > 2014) {
this._year = newValue;
this.edition += newValue - 2014;
}
}
});
book.year = 2015;
alert(book.edition); // 2
_year中的下劃線是一種常用標記,表示只能通過對象方法訪問的屬性。
2.定義多個屬性
JavaScript定義了Object.definePerperties(),用於定義多個對象參數。
var book = {};
Object.defineProperties(book, {
_year:{
value : 2016
},
edition:{
value : 1
},
year : {
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2015) {
this._year = newValue;
this.edition += newValue - 2015;
}
}
}
});
上面在book對象上定義了兩個數據屬性(_year和edition)和一個訪問器屬性(year)。
3.讀取屬性的特性
JavaScript提供了Object.getOwnPropertyDescriptor()方法,用於取得給定屬性的描述符。接收兩個參數:屬性所在的對象和要讀取其描述符的屬性名稱。結果返回一個對象。
var book = {};
Object.defineProperties(book, {
_year: {
value: 2016
},
edition: {
value: 1
},
year:{
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2016) {
this._year = newValue;
this.edition += newValue - 2015;
}
}
}
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value); // 2016
alert(descriptor.configurable); // false
alert(typeof descriptor.get); // "undefined"
var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value); // undefined
alert(descriptor.enumerable); // false
alert(typeof descriptor.get); // "function"
對於數據屬性_year,value等於最初的值,configurable是false,而get等於undefined。對於訪問器屬性year,value等於undefined,enumerable是false,而get是一個執行getter函數的指針。