成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript創(chuàng)建對象與繼承方法(筆記)

go4it / 729人閱讀

摘要:因而可更改為增加屬性這種寫法要注意,創(chuàng)建實例一定要在定義原型之后,因為重寫原型對象就切斷了構(gòu)造函數(shù)與最初原型的聯(lián)系。借用構(gòu)造函數(shù)的問題還是和構(gòu)造函數(shù)創(chuàng)建對象一樣,方法都在構(gòu)造函數(shù)定義,函數(shù)復用就無從談起了。

一.創(chuàng)建對象
雖然Object構(gòu)造函數(shù)或?qū)ο笞置媪靠梢杂脕韯?chuàng)建單個對象,但有個明顯缺點:使用同一個接口創(chuàng)建很多對象會產(chǎn)生大量重復代碼。因而大家開始探索其他方式。
1.工廠模式

function createPerson (name, age) {
    var o = new Object():
    o.name = name;
    o.age = age;
    o.sayName = function () {
        console.log(this.name);
    }
    return o;
}
var person = createPerson("Lily", 12);

工廠模式特點:雖然解決了創(chuàng)建多個相似對象的問題,但卻無法識別一個對象的類型。(instance of)
2.構(gòu)造函數(shù)模式

function Person (name, age) {
    this.name = name;
    this.age = age;
    this.sayName = function () {
        console.log(this.name);
    }
}
var person = new Person("Lily", 12); //使用構(gòu)造函數(shù)模式創(chuàng)建實例,必須使用new操作符。

構(gòu)造函數(shù)模式特點:可以將它的實例標識為一種特定類型,但每個方法都要在實力上重新創(chuàng)建一遍。
3.原型模式

function Person () {}
Person.prototype.name = "Lily";
Person.prototype.age = 12;
Person.prototype.sayName = function () {
    console.log(this.name);
}
var person = new Person(); //使用hasOwnProperty方法可以檢測一個屬性存在于實例還是原型。
console.log(person.hasOwnProperty("name")); //false
person.name = "Tom"; //來自實例
console.log(person.hasOwnProperty("name")); //true

更簡單的原型語法:

function Person () {}
Person.prototype = {
    name: "Lily",
    age: 12,
    sayName: function () {
        console.log(this.name);
    }
} //這樣寫會導致constructor屬性不再指向Person了。(無論何時創(chuàng)建一個新函數(shù)A,都會為它創(chuàng)建一個prototype屬性,指向函數(shù)的原型對象,默認情況下,所有原型對象都會獲得一個constructor屬性,包含一個指向A的指針。)

因而可更改為:

function Person () {}
Person.prototype = {
    constructor: Person, //增加constructor屬性
    name: "Lily",
    age: 12,
    sayName: function () {
        console.log(this.name);
    }
} //這種寫法要注意,創(chuàng)建實例一定要在定義原型之后,因為重寫原型對象就切斷了構(gòu)造函數(shù)與最初原型的聯(lián)系。

原型模式的特點:實現(xiàn)了讓所有實例共享原型對象所包含的屬性和方法。但缺點也在于這種共享對于包含引用類型值的屬性而言,存在一些問題,即所有實例會共享一個數(shù)組或者對象。
4.組合構(gòu)造函數(shù)模式和原型模式

function Person (name, age) {
    this.name = name;
    this.age = age;
    this.friends = ["Tom", "Bob"];
}
Person.prototype = {
    constructor: Person,
    sayName: function () {
        console.log(this.name);
    }
}

構(gòu)造函數(shù)模式用于定義實例屬性,而原型模式用于定義方法和共享的屬性。這是目前最廣泛,認同度最高的方法。
5.動態(tài)原型模式
有其他OO語言經(jīng)驗的開發(fā)人員看到獨立的構(gòu)造函數(shù)和原型,可能會困惑。動態(tài)原型模式則是致力于解決此問題的一個方案,它把所有信息都封裝在了構(gòu)造函數(shù)中,在必要情況下,通過在構(gòu)造函數(shù)中初始化原型,保持了組合使用構(gòu)造函數(shù)和原型的優(yōu)點。

function Person (name, age) {
    this.name = name;
    this.age = age;
    this.friends = ["Tom", "Bob"];
    if (type of this.sayName != "function") {
        Person.prototype.sayName = function () {
            console.log(this.name);
        }
    } //if語句只需檢查一個初始化應(yīng)該存在的共享屬性或方法即可。
}

使用動態(tài)原型模式要記得不能用對象字面量重寫原型,因為如果在創(chuàng)建了實例的情況下重寫原型。那么就會切斷現(xiàn)有實例與新原型的聯(lián)系。
關(guān)于寄生構(gòu)造模式和穩(wěn)妥構(gòu)造模式,在工程實踐用的不多且稍顯過時,就不贅述了。有時間可以了解es6的class。
二.繼承
1.原型鏈

function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function () {
    return this.property;
}
function SubType(){
    this.property = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function () {
    return this.property;
}

需要注意的是,在通過原型鏈實現(xiàn)繼承時,不能用對象字面量創(chuàng)建原型方法,因為這樣會重寫原型鏈。如下所示:

function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function () {
    return this.property;
}
function SubType(){
    this.property = false;
}
SubType.prototype = new SuperType();
SubType.prototype = {
    getSubValue: function () {
        return this.subproperty;
    },
    someOtherMethod: function () {
        return false;
    }
} //這樣會導致SubType的實例無法訪問到getSuperValue()方法了。

原型鏈繼承的問題:
1.共享實例屬性,如果SupeType中定義一個數(shù)組colors,當subType通過原型鏈繼承SuperType后,它也會擁有一個colors屬性(就像專門創(chuàng)建了一個subType.prototype.colors屬性一樣),結(jié)果是SubType所有實例都會共享這個屬性。對其中一個實例.colors屬性會影響到所有其他實例。
2.在創(chuàng)建子類型的實例時,沒辦法在不影響所有對象實例的情況下,向超類型的構(gòu)造函數(shù)傳遞參數(shù)。
因此實踐中很少多帶帶使用原型鏈繼承。
2.借用構(gòu)造函數(shù)

function SuperType (name) {
    this.name = name;
    this.colors = ["red", "blue", "yellow"];
}
function SubType () 
    SuperType.call(this, "Lily");
    this.age = 12;
} //使用這種方式就可以向超類型的構(gòu)造函數(shù)傳參啦。

借用構(gòu)造函數(shù)的問題:還是和構(gòu)造函數(shù)創(chuàng)建對象一樣,方法都在構(gòu)造函數(shù)定義,函數(shù)復用就無從談起了。
3.組合繼承
使用原型鏈實現(xiàn)對原型屬性和方法的繼承,而通過構(gòu)造函數(shù)實現(xiàn)對實例屬性的繼承。

function SuperType (name) {
    this.name = name;
    this.colors = ["red", "blue", "yellow"];
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
};
function SubType (name, age) 
    // 繼承實例屬性
    SuperType.call(this, name); //第二次調(diào)用SuperType()
    this.age = age;
}
//繼承方法
SubType.prototype = new SuperType(); //第一次調(diào)用SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {
    console.log(this.age);
}
var instance1 = new SubType("Lily", 12);
instance1.colors.push("green");
console.log(instance1.colors); // "red,blue,yellow,green"
var instance2 = new SubType("Lucy", 22);
console.log(instance1.colors); // "red,blue,yellow"

組合繼承避免了原型鏈和借用構(gòu)造函數(shù)的缺陷,是一種較為流行的繼承方式。但是它還存在一個缺點:在第一次調(diào)用superType時,SubType.prototype會得到兩個屬性:name和colors,當調(diào)用SubType的構(gòu)造函數(shù)時又會再調(diào)用一次SuperType構(gòu)造函數(shù),在對象實例上創(chuàng)建了實例屬性name和colors屏蔽了SubType原型中的同名屬性。
寄生組合式繼承
寄生組合式是組合式繼承的改進,思路是不必為了指定子類的原型而調(diào)用超類的構(gòu)造函數(shù),僅復制超類的原型即可。

function SuperType (name) {
    this.name = name;
    this.colors = ["red", "blue", "yellow"];
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
};
function SubType (name, age) 
    // 繼承實例屬性
    SuperType.call(this, name); 
    this.age = age;
}
//繼承方法
SubType.prototype = Object.create(SuperType.prototype);
//Object.create(obj)相當于 function F(){}; F.prototype = obj;return new F();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {
    console.log(this.age);
}

開發(fā)人員普遍認為寄生組合式繼承是引用類型最理想的繼承方法。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/97987.html

相關(guān)文章

  • JavaScript面向對象編程學習筆記---概念定義

    摘要:子類繼承自父類的方法可以重新定義即覆寫,被調(diào)用時會使用子類定義的方法什么是多態(tài)青蛙是一個對象,金魚也是一個對象,青蛙會跳,金魚會游,定義好對象及其方法后,我們能用青蛙對象調(diào)用跳這個方法,也能用金魚對象調(diào)用游這個方法。 1、專用術(shù)語 面向?qū)ο缶幊坛绦蛟O(shè)計簡稱:OOP,在面向?qū)ο缶幊讨谐S玫降母拍钣校簩ο?、屬性、方法、類、封裝、聚合、重用與繼承、多態(tài)。 2、什么是對象? 面向?qū)ο缶幊痰闹攸c...

    mikasa 評論0 收藏0
  • 《你不知道的javascript筆記_對象&原型

    摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學習清單,發(fā)現(xiàn)僅有部分完成了。當然,這并不影響年是向上的一年在新的城市穩(wěn)定連續(xù)堅持健身三個月早睡早起游戲時間大大縮減,學會生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學習清單,發(fā)現(xiàn)僅有部分完成了。當然,這并不影響2018年是向上的一年:在新的城市穩(wěn)定、...

    seasonley 評論0 收藏0
  • Javascript 設(shè)計模式讀書筆記(三)——繼承

    摘要:的繼承方式屬于原型式繼承,非常靈活。當使用關(guān)鍵字執(zhí)行類的構(gòu)造函數(shù)時,系統(tǒng)首先創(chuàng)建一個新對象,這個對象會繼承自構(gòu)造函數(shù)的原型對象新對象的原型就是構(gòu)造函數(shù)的屬性。也就是說,構(gòu)造函數(shù)用來對生成的新對象進行一些處理,使這個新對象具有某些特定的屬性。 繼承這個東西在Javascript中尤其復雜,我掌握得也不好,找工作面試的時候在這個問題上栽過跟頭。Javascript的繼承方式屬于原型式繼承,...

    cangck_X 評論0 收藏0
  • javascript高級程序設(shè)計》第六章 讀書筆記javascript繼承的6種方法

    摘要:繼承的是超類型中構(gòu)造函數(shù)中的屬性,如上繼承了屬性,但沒有繼承原型中的方法。上述造成的結(jié)果是子類型實例中有兩組超類型的構(gòu)造函數(shù)中定義的屬性,一組在子類型的實例中,一組在子類型實例的原型中。 ECMAScript只支持實現(xiàn)繼承,主要依靠原型鏈來實現(xiàn)。與實現(xiàn)繼承對應(yīng)的是接口繼承,由于script中函數(shù)沒有簽名,所以無法實現(xiàn)接口繼承。 一、原型鏈 基本思想:利用原型讓一個引用類型繼承另一個引用...

    孫吉亮 評論0 收藏0
  • JavaScript學習第十天筆記繼承

    摘要:繼承原型鏈如果構(gòu)造函數(shù)或?qū)ο蟮脑椭赶驑?gòu)造函數(shù)或?qū)ο螅脑驮僦赶驑?gòu)造函數(shù)或?qū)ο?,以此類推,最終的構(gòu)造函數(shù)或?qū)ο蟮脑椭赶虻脑汀? 繼承 原型鏈 如果構(gòu)造函數(shù)或?qū)ο驛的原型指向構(gòu)造函數(shù)或?qū)ο驜,B的原型再指向構(gòu)造函數(shù)或?qū)ο驝,以此類推,最終的構(gòu)造函數(shù)或?qū)ο蟮脑椭赶騉bject的原型。由此形成了一條鏈狀結(jié)構(gòu),被稱之為原型鏈。按照上述的描述,在B中定義的屬性或方法,可以在A中使用并不需要...

    baiy 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<