1. 程式人生 > >讀書筆記之面向對象的程序設計-1理解對象

讀書筆記之面向對象的程序設計-1理解對象

-i chrom conf 理解 cnblogs object ftw 不能 pro

ECMA-262把對象定義為:“無序屬性的集合,其屬性可以包含基本值、對象或者函數。” 創建自定義對象的最簡單方式就是創建一個Object的實例 eg:先創建一個名為person的對象,並為他添加了三個屬性和一個方法。
1 var person = new Object();
2 person.name = "Nicholas";
3 person.age = 29;
4 person.job = "Software Engineer";
5 person.sayName = function(){
6           alert(this.name);
7 };

上面是早期寫法,現在對象字面量成為創建這種對象的首選模式。前面的例子可以表示如下。

1 var person = {
2     name: "Nicholas",
3     age: 29,
4     job:"Software Engineer",
5     sayName: function(){
6         alert(this.name);
7     }
8 };

一、屬性類型

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

1、數據屬性

數據屬性包含一個數據值的位置。在這個位置可以讀取和寫入值。數據屬性有4個可以描述其行為的特性。

[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。默認值為true; [[Enumerable]]:表示能否通過for-in循環返回屬性。默認值為true; [[Writable]]:表示能否修改屬性的值。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為true。 [[Value]]:包含這個屬性的數據值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。這個特性的默認值為undefined。 要修改屬性默認的特性,必須使用ECMAScript 5的Object.defineProperty()方法。這個方法接收三個參數:屬性所在的對象、屬性的名字和一個描述符對象。其中,描述符(descriptor)對象的屬性必須是:configurable、enumerable、writable和value。設置其中的一或多個值,可以修改對應的特性值。
var person = {};
Object.defineProperty(person, "name", {
    configurable: false,  //禁止修改
    value: "Nicholas"
});
console.log(person.name); //Nicholas
delete person.name;  //嚴格模式下會拋出錯誤。
console.log(person.name); //Nicholas
在調用Object.defineProperty()方法時,如果不指定,configurable、enumerable和writable特性的默認值都是false。多數情況下,可能都沒有必要利用Object.defineProperty()方法提供的這些高級功能。 attention:IE8是第一個實現Object.defineProperty()方法的瀏覽器版本。然而,這個版本的實現存在諸多限制:只能在DOM對象上使用這個方法,而且只能創建訪問器屬性。由於實現不徹底,建議不要在IE8中使用Object.defineProperty()方法。 2、訪問器屬性 訪問器屬性不包含數據值;它們包含一對getter和setter函數(非必需)。在讀取訪問器屬性時,會調用getter函數,該函數負責返回有效的值;在 寫入訪問器屬性時,會調用setter函數並傳入新值,該函數負責決定如何處理函數。訪問器屬性有4個特性: [[Configurable]]:同數據屬性特性; [[Enumerable]]:同數據屬性特性; [[Get]]:在讀取屬性時調用的函數。默認值為undefined; [[Set]]:在寫入屬性時調用的函數。默認值為undefined。 訪問器屬性不能直接定義,必須使用Object.defineProperty()來定義(IE8報錯)。
var book = { 
    _year: 2004,  
    edition: 1 
};   //創建book對象,並定義兩個屬性。
_year前面的下劃線是一種常用的記號,用於表示只能通過對象方法訪問的屬性。

Object.defineProperty(book, "year", {   //訪問器屬性year則包含一個getter函數和一個setter函數。getter函數返回_year的值,setter函數通過計算來確定正確的版本。
    get: function(){ 
        return this._year; 
    }, 
    set: function(newValue){ 
        if (newValue > 2004) { 
            this._year = newValue; 
            this.edition += newValue - 2004; 
        } 
    } 
}); 
book.year = 2005;   //把year屬性修改為2005會導致_year變成2005,而edition變為2。
alert(book.edition);  //2 

上面例子是使用訪問器屬性的常見方式,即設置一個屬性的值會導致其他屬性發生變化。

支持ECMAScript 5的這個方法(Object.defineProperties()方法)的瀏覽器有IE9+(IE8只是部分實現)、Firefox 4+、Safari 5+、Opera12+和Chrome。 二、定義多個屬性 利用Object.defineProperties()可以通過描述一次定義多個屬性。這個方法接收兩個對象參數:第一個對象是要添加和修改其屬性的對象,第二個對象的屬性與第一個對象中要添加或修改的屬性一一對應。
var book = {}; 
Object.defineProperties(book, { 
    _year: { 
        value: 2004 
    }, 
    edition: { 
        value: 1 
    }, 
    year: { 
        get: function(){ 
            return this._year; 
        }, 
        set: function(newValue){ 
            if (newValue > 2004) { 
                this._year = newValue; 
                this.edition += newValue - 2004; 
            } 
        } 
    } 
}); //book對象上定義了兩個數據屬性(_year和edition)和一個訪問器屬性(year)。


三、讀取屬性的特性

使用ECMAScript 5的Object.getOwnPropertyDescriptor()方法,可以取得給定屬性的描述符。這個方法接收兩個參數:屬性所在的對象和要讀取其描述符的屬性名稱。返回值是一個對象,如果是訪問器屬性,這個對象的屬性有configurable、enumerable、get和set;如果是數據屬性,這個對象的屬性有configurable、enumerable、writable和value。
var book = {}; 
Object.defineProperties(book, { 
    _year: {  
        value: 2004 
    }, 
    edition: { 
        value: 1 
    }, 
    year: { 
        get: function(){ 
            return this._year; 
        }, 
        set: function(newValue){ 
            if (newValue > 2004) { 
                this._year = newValue; 
                this.edition += newValue - 2004; 
            } 
        } 
    } 
}); 
var descriptor = Object.getOwnPropertyDescriptor(book, "_year"); 
console.log(descriptor);      //{configurable: false, enumerable: false, value: 2004, writable: false} alert(descriptor.value);      //2004 alert(descriptor.configurable);  //false alert(typeof descriptor.get);   //"undefined" var descriptor = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor);      //{configurable: false, enumerable: false} 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函數的指針。

attention:在JavaScript中,可以針對任何對象——包括DOM和BOM對象,使用Object.getOwnProperty-Descriptor()方法。支持這個方法的瀏覽器有IE9+、Firefox 4+、Safari 5+、Opera 12+和Chrome。

讀書筆記之面向對象的程序設計-1理解對象