描述符和命名屬性
屬性是物件的成員。每個命名屬性都是一對(名稱,描述符)。名稱是允許訪問的字串(使用點符號 object.propertyName
或方括號表示 object['propertyName']
)。描述符是在訪問屬性時定義屬性的 bevahiour 的欄位記錄(屬性發生了什麼以及訪問它時返回的值是什麼)。總的來說,屬性將名稱與行為相關聯(我們可以將行為視為黑盒子)。
有兩種型別的命名屬性:
- data 屬性 :屬性的名稱與值相關聯。
- accessor 屬性 :屬性的名稱與一個或兩個訪問器函式相關聯。
示範:
obj.propertyName1 = 5; //translates behind the scenes into
//either assigning 5 to the value field* if it is a data property
//or calling the set function with the parameter 5 if accessor property
//*actually whether an assignment would take place in the case of a data property
//also depends on the presence and value of the writable field - on that later on
屬性的型別由其描述符的欄位確定,屬性不能同時屬於這兩種型別。
資料描述符 -
- 必填欄位:
value
或writable
或兩者 - 可選欄位:
configurable
,enumerable
樣品:
{
value: 10,
writable: true;
}
訪問者描述符 -
- 必填欄位:
get
或set
或兩者 - 可選欄位:
configurable
,enumerable
樣品:
{
get: function () {
return 10;
},
enumerable: true
}
欄位的含義及其預設值
configurable
,enumerable
和 writable
:
- 這些鍵都預設為
false
。 - 當且僅當可以更改此屬性描述符的型別並且可以從相應物件中刪除屬性時,
configurable
才是true
。 - 當且僅當在列舉相應物件上的屬性期間顯示此屬性時,
enumerable
才是true
。 - 當且僅當與屬性關聯的值可以使用賦值運算子更改時,
writable
才是true
。
get
和 set
:
- 這些鍵預設為
undefined
。 get
是一個作為屬性 getter 的功能,如果沒有 getter 則可以作為 getter。函式 return 將用作屬性的值。set
是一個函式,可以作為屬性的設定者,如果沒有 setter,則為undefined
。該函式將僅接收分配給屬性的新值作為引數。
value
:
- 此鍵預設為
undefined
。 - 與屬性相關的價值。可以是任何有效的 JavaScript 值(數字,物件,函式等)。
例:
var obj = {propertyName1: 1}; //the pair is actually ('propertyName1', {value:1,
// writable:true,
// enumerable:true,
// configurable:true})
Object.defineProperty(obj, 'propertyName2', {get: function() {
console.log('this will be logged ' +
'every time propertyName2 is accessed to get its value');
},
set: function() {
console.log('and this will be logged ' +
'every time propertyName2\'s value is tried to be set')
//will be treated like it has enumerable:false, configurable:false
}});
//propertyName1 is the name of obj's data property
//and propertyName2 is the name of its accessor property
obj.propertyName1 = 3;
console.log(obj.propertyName1); //3
obj.propertyName2 = 3; //and this will be logged every time propertyName2's value is tried to be set
console.log(obj.propertyName2); //this will be logged every time propertyName2 is accessed to get its value