JS 對象(3)—屬性類型


屬性類型

JS中有兩種屬性:數據屬性和訪問器屬性。

 

數據屬性

數據屬性包含一個數據值的位置;在這個位置可以讀取和寫入值。

數據屬性具有4個描述其行為的特性:

 

[[Configurable]]

表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,能否把屬性修改為訪問器屬性。

直接在對象上定義的屬性,默認為true。

 

[[Enumerable]]

表示能否通過for-in循環返回屬性。

直接在對象上定義的屬性,默認為true。

除了for-in循環之外,ECMAScript5定義了兩個用以枚舉屬性名稱的函數。

Object.keys()返回一個數組,這個數組由對象中可枚舉的自有屬性的名稱組成。

其工作原理類似這樣:

 1 function keys(object) {
 2     if(typeof object !== "object") {
 3         throw TypeError;    //參數必須是對象
 4     };
 5     var result = [];    //創建一個數組,用以保存枚舉的屬性
 6     for (prop in object) {    //遍歷所有可枚舉的屬性
 7         if (object.hasOwnProperty(prop)) {    //判斷是否為自有屬性
 8             result.push(prop);    //將屬性名添加到數組
 9         };
10     };
11     return result;    //返回數組
12 };

 

Object.getOwnPropertyNames()返回對象的所有自有屬性的名稱,而不僅限於可枚舉的屬性。

 

[[Writable]]

表示能否修改屬性的值。

直接在對象上定義的屬性,默認為true。

 

[[Value]]

包含這個屬性的數據值;讀取屬性值的時候,從這個位置讀取;寫入屬性值的時候,把值保存在這里。

這個特性默認為undefined。

 

訪問器屬性

訪問器屬性包含一對getter和setter方法。

如果屬性同時具有getter和setter方法,那么它就是一個讀/寫屬性;如果只有getter方法,則為只讀屬性;同理,如果只有setter方法,則為只寫屬性。

訪問器屬性有如下4個特性:

 

[[Configurable]]

表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,能否把屬性修改為數據屬性。

直接在對象上定義的屬性,默認為true。

 

[[Enumerable]]

表示能否通過for-in循環返回屬性。

直接在對象上定義的屬性,默認為true。

 

[[Get]]

在讀取屬性時調用的函數;默認值為undefined。

在讀取訪問器屬性時,會調用gette方法,這個函數負責返回有效的值。

 

[[Set]]

在寫入屬性時調用的函數;默認值為undefined。

在寫入訪問器屬性時,會調用setter方法並傳入新值,這個函數負責決定如何處理數據。

訪問器屬性不能直接定義,必須使用Object.defineProperties()方法來定義。

 

定義多個屬性

要修改數據屬性默認的特性,必須使用ECMAScript5中的Object.defineProperty()方法;接受三個參數:屬性所在的對象、屬性的名字、描述符對象;其中,數據屬性描述符對象的屬性必須是:configurable、enumerable、writable、value;訪問器屬性的描述符對象的屬性有configurable、enumerable、get、set。設置其中的一個或多個值,可以修改對應的特性值。

1 var person = {};
2 Object.defineProperty(person, "name", {
3     writable: false,
4     value: "CC"
5 });
6 alert(person.name);    //"CC"
7 person.name = "VV";
8 alert(person.name);    //"CC"

在調用Object.defineProperty()方法新建屬性時,如果不指定,configurable、enumerable、writable特性的值都是false。

注意:使用Object.defineProperty()方法,要么修改已有屬性,要么新建自有屬性,不能修改繼承屬性。

 

Object.defineProperties()方法,通過描述符一次性定義多個屬性;

接收兩個對象參數:第一個對象是要添加或修改其屬性的對象;第二個對象的屬性與第一個對象中要添加或修改的屬性一一對應。

 1 var person = {};
 2 Object.defineProperties(person, {
 3     name: {
 4         value: "CC",
 5         writable: true
 6     },
 7     age: {
 8         value: 23,
 9         writable: false
10     }
11 });
12 alert(person.name);    //"CC"
13 person.name = "VV";
14 alert(person.name);    //"VV"

 

讀取屬性的特性

Object.getOwnPropertyDescriptor()方法,可以取得給定屬性的描述符;

接收兩個參數:屬性所在的對象,要讀取其描述符的屬性名稱。

返回值是一個對象;如果是數據屬性,這個對象的屬性有configurable、enumerable、writable、value;如果是訪問器屬性,這個對象的屬性有configurable、enumerable、get、set。

 1 var person = {};
 2 Object.defineProperties(person, {
 3     name: {
 4         value: "CC",
 5         writable: true
 6     },
 7     age: {
 8         value: 23,
 9         writable: false
10     }
11 });
12 var descriptor = Object.getOwnPropertyDescriptor(person, "name");
13 alert(descriptor.value);       //"CC"
14 alert(descriptor.writable);    //true

 

注意:

Object.getOwnPropertyDescriptor()方法,只能用於實例屬性;如果要取得原型屬性的描述符,必須直接在原型對象上調用Object.getOwnPropertyDescriptor()方法。

《JS權威指南》——Object.getOwnPropertyDescriptor()方法只能取得自有屬性的描述符,要想獲得繼承的屬性,必須遍歷原型鏈。

 

屬性的特性規則

如果對象是不可擴展的,則可以編輯已有的自有屬性,但不能添加新屬性;

如果屬性是不可配置的,則不能修改它的可配置性和可枚舉性(一旦將confidurable特性改為false,不能再改回true);

如果訪問器屬性是不可配置的,則不能修改其getter和setter方法,也不能將其轉換為數據類型;

如果數據屬性是不可配置的,則不能將它的writable特性從false改為true,但可以從true改為false;也不能將其轉換為訪問器屬性;

如果數據屬性是不可配置且不可寫的,則不能修改它的value值;然而可配置但不可寫的value值是可以修改的(實際上是先標記為可寫的,然后修改value值,最后轉換為不可寫的)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM