【JavaScript】【學習】對象的創建和繼承

    下午剛剛看完了《JavaScript高級程序設計》中的第六章,面向對象的程序設計,因爲自己以前沒有面向對象程序設計的基礎,所以理解得有些困難,但是通過自己的努力研讀+上網查資料+反覆實踐,總算是答題上理解了,對我的編程思維算是一個很大的提高吧,這裏把學習筆記和心得發一下,方便以後自己查閱。

    一、理解對象

    在JavaScript中,一切皆是對象,前面學習引用類型,基本都是JavaScript中的內置對象,而基本類型,則都是這些內置對象的實例,BOM,DOM也是對象,全局變量可以視爲window的屬性。

    學習JavaScript,最重要的就是理解對象這個概念,因爲我們所有的語句,處理的都是對象。

    在ECMAScript的概念中,對象被定義爲:無序屬性的集合,器屬性可以包含基本值,對象,或函數。

    所有的函數應該是方法,如果函數不是開發者創建的對象的屬性,那它就是window的屬性。

    二、對象的創建

    創建對象的模式包括:工廠模式、構造函數模式、原型模式、組合模式、動態原型模式、寄生構造函數模式和穩妥構造函數模式。

    1、工廠模式

    許多面嚮對象語言都使用類來創建對像,在JavaScript中,並沒有類的定義。JavaScript中的工廠模式將創建對象的細節封裝在一個函數中,當需要創建一個對象時,需要調用此函數。

    

function createObject(property1,property2,property3){
    var aObject = new Object();
    aObject.property1 = property1;
    aObject.property2 = property2;
    aObject.property3 = property3;
    aObject.method1 = function(){
        do something;
    };
    return aObject;
}

    工廠模式的問題在於它沒有解決對象識別的問題(怎樣識別一個對象)。

    2、構造函數模式

    構造函數模式的思路在於考慮到函數本身也是一個對象,而且函數沒有重載的特性,所以可以使用函數內部的this對象,來爲創建對象的函數添加屬性和方法,使構造函數成爲我們想要的對象。

    

function AObject(property1,property2,property3){
    this.property1 = property1;
    this.property2 = property2;
    this.property3 = property3;
    this.method1 = function(){
        do something... ;
    };
    }

    構造函數模式的問題在於每一次使用構造函數創建對象時,都會在後臺自動創建相應的方法函數,當對象的方法很多時,後臺會創建很多相同的函數,如果我們把方法函數取出到構造函數以外,由構造函數內部的方法去調用的話,又失去了函數的封裝性。

    3、原型模式

    原型模式的原理是利用了函數對象的prototype屬性,在JavaScript中,每一個對象都擁有一個prototype屬性,這個屬性指向了一個對象的原型,包含着this類型的所有對象實例所擁有的屬性和方法

    原型模式利用函數的prototype屬性,創建了一個基於此構造函數的原型對象,每當我們調用此構造函數創建對象實例時,我們創建的對象實例都會從這個prototype創建的原型繼承屬性和方法。這樣就解決了構造函數模式所面臨的問題

function Person(){
    Person.prototype.name = "wan";
    Person.prototype.age = 14;
    Person.prototype.sayName = function(){
        alert(this.name);};
}
var person1 = new Person();
person.sayName();

      我們也可以將Person.Prototype.name = "wan";等定義屬性的語句放到函數以外,也可以使用字面量語法爲原型添加屬性和方法。

      使用原型模式創建的對象實例,會重這個原型繼承屬性和方法,改寫實例的屬性,不會影響到原型和其它實例,創建一個同名屬性,會覆蓋繼承來的屬性,但不會影響原型和其它實例

       原型模式的問題在於,如果一個屬性是引用類型(比如數組),修改一個實例的屬性會影響到其他實例和原型。

    4、組合模式

    組合模式集成了構造函數模式和原型模式的有點,是目前使用最廣泛的創建對象模式。

    在組合模式中,我們將對象實例私有的屬性放在在構造函數中,將公共的屬性和方法放在原型中,既滿足了隱私性,又滿足了性能上的要求

    

function AObejct(property1,property2,property3){
    this.property1 = property1;
    this.property2 = property2;
    this.property3 = property3;
}
AObject.prototype.property4 = property4;
AObject.prototype.method1 = function(){
    do something... ;
}
var aObject = new AObject();

    5、動態原型模式

    組合模式的一個問題在於構造函數和原型分開了,動態原型將所有細節都封裝到了一個函數中,通過一個if語句,檢查一個對象是否已經擁有原型的方法,從而決定是否需要載入原型。

    6、寄生構造函數模式

    寄生構造函數模式與工廠模式唯一的區別在於調用構造函數前使用了new 操作符

    一般情況下,很少使用這種方法創建對象

   7、穩妥構造函數模式

    在對安全性要求較高的場合,可以使用問題構造函數模式構造穩妥對象,穩妥對象沒有公共屬性,其方法也不引用this值。


    二、繼承

    在面向對象程序設計中國,繼承表示一個對象獲得另I有一個對象的屬性和方法的過程

    在JavaScript中,實現繼承主要靠原型鏈。

    原型鏈的思想:每一個對象都有一個prototype屬性,這個屬性都可以使用這個prototype屬性創建一個原型對象,讓另一個對象等於這個原型對象,成爲原型的實例,實例便繼承了原對象的屬性和方法。而實例對象也可以利用自身的prototype屬性創建一個原型,來讓其它對象繼承,如此形成了一條長長的繼承鏈條,稱爲原型鏈。

    使用原型鏈繼承的方法:只要讓需要繼承的實例對象的prototype屬性等於被繼承對象的構造函數就行了。    

    

    如同創建對象時的原型模式一樣,原型鏈也存在引用類型的問題,如果修改一個實例的引用類型屬性,會影響到原型和其它實例。

    2、藉助構造函數

    構造函數的思想是在子類型的構造函數內部調用超類型的構造函數,調用時要用到函數地 call()或apply()方法,這樣每次創建函數時都會在函數作用域內調用超類型的構造函數

    如同創建對象時的構造函數模式,這種繼承方式也會產生性能上的問題。

    3、組合繼承

    組合繼承就是將私有的屬性和引用類型的屬性使用構造函數繼承,將共有的屬性和方法用原型鏈繼承。這也是目前應用比較廣泛的一種繼承方式。

    4、原型式繼承

    原型式繼承如同創建對象的工廠模式,它將繼承的過程封裝在一個函數中,在這個函數中,實現了對象的淺複製,這種方式適用於創建大量相似的對象而且無需考慮性能的環境。

    5、寄生式繼承

    寄生繼承模式是與原型式繼承緊密相關的一種繼承方式,它在使用原型式繼承的基礎上重寫了對象的方法來增強對象。

    6、寄生組合式繼承

    組合繼承模式在繼承過程中調用了2次超類型的構造函數,在某些場合不符合性能上的要求,於是寄生組合模式出現了,這種模式將寄生式繼承的繼承方式封裝在一個繼承函數中,使用子類型對象和超類型對象作爲參數,繼承的過程就只需調用一次繼承函數。

    


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章