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