摘要:第二個問題是在創(chuàng)建子類型的實例時,不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。實際上,應(yīng)該說是沒有辦法在不影響所有對象實例的情況下,給炒類型的構(gòu)造函數(shù)傳遞參數(shù)。借用構(gòu)造函數(shù)偽造對象或經(jīng)典繼承即在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù)。
繼承
許多 OO 語言支持兩種繼承方式:接口繼承和實現(xiàn)繼承。接口繼承只繼承方法簽名,而實現(xiàn)繼承則繼承實際的方法。如前所述,由于函數(shù)沒有簽名,在 ECMAScript 中無法實現(xiàn)接口繼承。 ECMAScript 只支持實現(xiàn)繼承,而且其實現(xiàn)繼承主要是依靠原型鏈來實現(xiàn)。
原型鏈基本思想是:利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。
構(gòu)造函數(shù)、原型和實例的關(guān)系:每個構(gòu)造函數(shù)都有一個原型對象,原型對象都包含一個指向構(gòu)造函數(shù)的指針,而實例都包含一個指向原型對象的內(nèi)部指針。
jsfunction SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; }; function SubType() { this.subproperty = false; } //繼承了 SuperType SubType.prototype = new SuperType(); SuperType.prototype.getSubValue = function() { return this.subproperty; } var instance = new SubType(); alert(instance.getSuperValue());//true
別忘記默認的原型
確定原型和實例的關(guān)系
jsalert(instance instanceof Object); //true alert(instance instanceof SuperType); //true alert(instance instanceof SubType); //true
jsalert(Object.prototype.isPrototypeOf(instance));//ture alert(SuperType.prototype.isPrototypeOf(instance));//ture alert(SubType.prototype.isPrototypeOf(instance));//ture
謹慎地定義方法
給原型添加方法的代碼一定要放在替換原型的語句之后。
jsfunction SuperType() { this.property = true; } SuperType.protype.getSuperValue = function() { return this.property; } function SubType() { this.subproperty = false; } //繼承了 SuperType SubType.prototype = new SuperType(); //添加新方法 SubType.prototype.getSubValue = function() { return this.subproperty; }; //重寫超類型中的方法 SubType.prototype.getSuperValue = function() { return false; }; var instance = new SubType(); alert(instance.getSuperValue());//false
jsfunction SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function SubType() { this.subproperty = false; } //繼承了 SuperType SubType.prototype = new SuperType(); //使用字變量添加新方法,會導致上一行代碼無效 SubType.prototype = { getSubValue : function() { return this.subproperty; }, someOtherMethod = function() { return false; } }; var instance = new SubType(); alert(instance.getSuperValue()); //error 原型鏈被切斷(現(xiàn)在的原型包含的是 Object 的實例)。
4.原型鏈的問題
最主要的問題來自包含引用類型值的原型。前面已經(jīng)介紹過包含引用類型值的原型屬性會被所有實例共享,這也是為什么要在構(gòu)造函數(shù)中而不在原型對象中定義屬性的原因。
第二個問題是:在創(chuàng)建子類型的實例時,不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。實際上,應(yīng)該說是沒有辦法在不影響所有對象實例的情況下,給炒類型的構(gòu)造函數(shù)傳遞參數(shù)。
即在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù)。函數(shù)只不過是在特定環(huán)境中執(zhí)行代碼的對象,所以可通過 apply() 或 call() 方法也可以在(將來)新創(chuàng)建的對象上執(zhí)行構(gòu)造函數(shù)。
jsfunction SuperType() { this.colors = ["red","blue","green"]; } function SubType() { //繼承了 SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green"
傳遞參數(shù)
js function SuperType(name) { this.name = name; } function SubType() { //繼承了 SuperType,同時還傳遞了參數(shù) SuperType.call(this,"PaddingMe"); //實例屬性 this.age = 25; } var instance = new SubType(); alert(instance.name); //"PaddingMe" alert(instance.age); //25組合繼承(偽經(jīng)典繼承)
即將原型鏈和借用構(gòu)造函數(shù)的方法組合在一起,思路為使用原型鏈實現(xiàn)對原型屬性和方法的繼承,而通過借用構(gòu)造函數(shù)來實現(xiàn)對實例屬性的繼承。
js function SuperType(name) { this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function() { alert(this.name); } function SubType() { //繼承屬性 SuperType.call(this,name); this.age = age; } SubType.prototype = new SuperType(); SubType.prototype.constuctor = SubType(); SubType.prototype.sayAge = function() { alert(this.age); } var instance1 = new("PaddingMe",25); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName; //"PaddingMe" instance1.sayAge; //25 var instance2 = new("hw",26); alert(instance2.colors); //"red,blue,green" instance2.sayName; //"hw" instance2.sayAge; //26原型式繼承
js function object(o) { function F(){} F.prototype = o; return new F(); } var person = { name : "PaddingMe"; friends :["hw","wjj","hz"]; } var antherPerson = object(person); antherPerson.name = "Hhb"; antherPerson.friends.push("zxp"); var yetAntherPerson = object(person); yetAntherPerson.name = "Linda"; yetAntherPerson.friends.push("him"); alert(person.friends)//"hw,wjj,hz,zxp,him"
ECMAScirpt 5 中新增 Object.create() 方法規(guī)范化了原型式繼承。有兩個參數(shù),一個用作新對象原型的對象和(可選的)一個為新對象定義額外屬性的對象。
在傳入一個參數(shù)情況下,Objetc.create() 和 object() 方法的行為相同。
js var person = { name : "PaddingMe"; friends :["hw","wjj","hz"]; } var antherPerson = Object.create(person); antherPerson.name = "Hhb"; antherPerson.friends.push("zxp"); var yetAntherPerson = Object.create(person); yetAntherPerson.name = "Linda"; yetAntherPerson.friends.push("him"); alert(person.friends)//"hw,wjj,hz,zxp,him"
第二個參數(shù)與 `Object.defineProperties() 方法的第二個參數(shù)格式相同: 每個屬性都是通過自己的描述符定義的。
js var person = { name : "PaddingMe"; friends :["hw","wjj","hz"]; } var anthorPerson = Object.create(person, { name: { value:"hehe"; } }) alert(anthorPerson.name);//"hehe"寄生式繼承
即創(chuàng)建一個僅用于封裝繼承構(gòu)成的函數(shù),該函數(shù)在內(nèi)部以某種方式來增強對象,最后再像真地是它做了所有工作一樣返回對象。
js function createAnother(original) { var clone = object(original); //通過調(diào)用函數(shù)創(chuàng)建一個新對象 clone.sayHi = function() { //以某種方式來增強這個對象 alert("hi"); }; return clone; //返回這個對象 } var person = { name : "PaddingMe"; friends :["hw","wjj","hz"]; } var anthorPerson = createAnother(person); anthorPerson.sayHi();//"hi"寄生組合式繼承
jsfunction SuperType(name) { this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function() { alert(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.constuctor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); }
所謂寄生組合式繼承,即通過借用構(gòu)造函數(shù)來繼承屬性,通過原型鏈的混成形式來繼承方法。基本思路為:不必為了指定子類型的原型而調(diào)用超類型的構(gòu)造函數(shù),我們所需要的無非是超類型原型的一個副本而已。本質(zhì)上,就是使用寄生式繼承來繼承超類型的原型,然后再將結(jié)構(gòu)指定給子類型的原型。寄生組合式繼承的基本模式:
js function inheritPrototype(subType,superType){ var prototype = object(superType.prototype); //創(chuàng)建對象 prototype.constructor = subType; //增強對象 subType.prototype = prototype; // 指定對象 }
jsfunction SuperType(name) { this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function() { alert(this.name); } function SubType(name,age) { SuperType.call(this,name); //第二次調(diào)用SuperType(); this.age = age; } inheritPrototype(SubType,SuperType); SubType.prototype.sayAge = function(){ alert(this.age); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85501.html
摘要:子類繼承自父類的方法可以重新定義即覆寫,被調(diào)用時會使用子類定義的方法什么是多態(tài)青蛙是一個對象,金魚也是一個對象,青蛙會跳,金魚會游,定義好對象及其方法后,我們能用青蛙對象調(diào)用跳這個方法,也能用金魚對象調(diào)用游這個方法。 1、專用術(shù)語 面向?qū)ο缶幊坛绦蛟O(shè)計簡稱:OOP,在面向?qū)ο缶幊讨谐S玫降母拍钣校簩ο?、屬性、方法、類、封裝、聚合、重用與繼承、多態(tài)。 2、什么是對象? 面向?qū)ο缶幊痰闹攸c...
摘要:實際上,可以將其理解為某種形式的繼承。如果上下文是,則使用全局對象代替。例如的第個參數(shù)是上下文,后續(xù)是實際傳入的參數(shù)序列中允許更換上下文是為了共享狀態(tài),尤其是在事件回調(diào)中。 公開記錄學習JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應(yīng)用開發(fā)》為主要學習資料。接上一篇類的學習,發(fā)現(xiàn)實在是看暈了,有些例子是能看懂在干嘛,但是不知道為什么這樣做,有的甚至...
摘要:繼承原型鏈如果構(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中使用并不需要...
摘要:即另外,注意到構(gòu)造函數(shù)里的屬性,都沒有經(jīng)過進行初始化,而是直接使用進行綁定。并且在模式下,構(gòu)造函數(shù)沒有使用進行調(diào)用,也會導致報錯。調(diào)用構(gòu)造函數(shù)千萬不要忘記寫。 1. 基礎(chǔ) JavaScript不區(qū)分類和實例的概念,而是通過原型來實現(xiàn)面向?qū)ο缶幊?。Java是從高級的抽象上設(shè)計的類和實例,而JavaScript的設(shè)計理念,聽起來就好比Heros里的Peter,可以復(fù)制別人的能力。JavaS...
摘要:例例通過原型鏈來檢測對象所調(diào)用的方法是否存在,存在在哪個原型對象上除了在對象對象中存在外,其他方法都是通過原型鏈的方法在上找到并調(diào)用。 前言 學習了解JavaScript對象的繼承機制 JavaScript Object 概念 Object是js的基本數(shù)據(jù)結(jié)構(gòu)的一種,屬于引用類型。 對象的創(chuàng)建方法 對象字面量寫法 構(gòu)造函數(shù),通過構(gòu)造函數(shù)來創(chuàng)建對象實例 Object()構(gòu)造函數(shù) cre...
閱讀 808·2021-10-14 09:43
閱讀 2133·2021-09-30 09:48
閱讀 3456·2021-09-08 09:45
閱讀 1103·2021-09-02 15:41
閱讀 1898·2021-08-26 14:15
閱讀 786·2021-08-03 14:04
閱讀 2985·2019-08-30 15:56
閱讀 3081·2019-08-30 15:52