摘要:實(shí)現(xiàn)繼承的方法借用構(gòu)造函數(shù)解決原型中包含引用類型所帶來(lái)的問(wèn)題的過(guò)程中,使用借用構(gòu)造函數(shù)偽造對(duì)象或經(jīng)典繼承來(lái)實(shí)現(xiàn)繼承。
繼承
在ECMAScript中繼承主要是依靠原型鏈來(lái)實(shí)現(xiàn)的。
實(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)部指針。
實(shí)現(xiàn)原型鏈
假如原型對(duì)象等于另一個(gè)類型的實(shí)例,此時(shí)該原型對(duì)象將包含指向另一個(gè)原型的指針,相應(yīng)的另一個(gè)原型中也包含著一個(gè)指針指向另一個(gè)構(gòu)造函數(shù)的指針。這樣層層遞進(jìn),就構(gòu)成了實(shí)例與原型之間的鏈條。這就是原型鏈的基本概念。
判斷原型和實(shí)例的關(guān)系
可以通過(guò)兩種方式來(lái)確定原型和實(shí)例之間關(guān)系。
使用instanceof操作符,只要用這個(gè)操作符來(lái)測(cè)試實(shí)例和原型鏈中出現(xiàn)的構(gòu)造函數(shù),結(jié)果就一定返回true。
alert(instance instanceof Object); //true
使用isprototypeOf()方法,同樣只要是原型鏈中出現(xiàn)過(guò)得原型,都可以說(shuō)是原型鏈所派生的實(shí)例的原型。isportotypeOf()也會(huì)返回true
alert(Object.prototype.isPrototypeOf(instance)); //true
所有引用類型都默認(rèn)繼承了Object
原型鏈存在的問(wèn)題
在通過(guò)原型來(lái)實(shí)現(xiàn)繼承時(shí),原型實(shí)際上會(huì)變成另一個(gè)類型的實(shí)例。原先的實(shí)例屬性就變成了現(xiàn)在的原型屬性了。
function SuperType(){ this.color=["red","blue","green"] } function SubType(){ } SubType.prototype = new SuperType();//繼承了SuperType(); var instance1 = new SubType(); instance1.color.push("black"); console.log(instance1.color); //"red,blue,green,black" var instance2 = new SubType(); console.log(instance2.color); //"red,blue,green,black"
SuperType構(gòu)造函數(shù)定義了一個(gè)colors屬性,SuperType的每個(gè)實(shí)例都會(huì)有各自包含自己數(shù)組的color屬性。當(dāng)SubType通過(guò)原型鏈繼承了SuperType之后,subType.prototype就變成了SuperType的一個(gè)實(shí)例,因此它也就擁有了自己的color屬性。那SubType的所有實(shí)例都會(huì)共享這個(gè)color屬性。 2. 在創(chuàng)建子類型的實(shí)例時(shí),不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。實(shí)現(xiàn)繼承的方法 1. 借用構(gòu)造函數(shù)
解決原型中包含引用類型所帶來(lái)的問(wèn)題的過(guò)程中,使用借用構(gòu)造函數(shù)(偽造對(duì)象或經(jīng)典繼承)來(lái)實(shí)現(xiàn)繼承。主要是通過(guò)使用apply()和call()方法在新創(chuàng)建的對(duì)象上執(zhí)行構(gòu)造函數(shù)如下:
function SuperType(){ this.color=["red","blue","green"] } function SubType(){ //繼承了SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.color.push("black"); console.log(instance1.color) //"red, blue,green,black" var instance2 = new SubType(); console.log(instance2.color) //"red,blue,green"
通過(guò)call()或apply()方法在新創(chuàng)建的SubType實(shí)例的環(huán)境下調(diào)用了SuperType構(gòu)造函數(shù)
相對(duì)原型鏈,借用構(gòu)造函數(shù)可以子類型構(gòu)造函數(shù)中向超類型構(gòu)造函數(shù)傳遞參數(shù)如下:
function SuperType(name){ this.name=name; } function SubType(){ //繼承了SuperType 同時(shí)還傳遞了參數(shù) SuperType.call(this,"aa"); //實(shí)例屬性 this.age=29; } var instance = new SubType(); alert(instance.name) // aa alert(instance.age) //29
### 2. 組合繼承
組合繼承也叫做偽經(jīng)典繼承將原型鏈和借用構(gòu)造函數(shù)的技術(shù)組合到一塊,從而發(fā)揮二組之所長(zhǎng)的一種繼承模式。思路是使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,而通過(guò)借用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。
function SuperType(name){ this.name=name; this.color = ["red","blue","green"] }; SuperType.prototype.sayName = function(){ alert(this.name) }; function SubType(name,age){ //繼承屬性 SuperType.call(this,name); this.age=age; } //繼承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType("aaa",29); instance1.color.push("black"); alert(instance1.color); //"red,blue,green,black" instance1.sayName(); //"aaa" instance1.sayAge(); // 29 var instance2 = new SubType("ccc",30); alert(instance2.color); //"red,blue,green" instance2.sayName(); //"ccc" instance2.sayAge(); // 30
組合繼承避免了原型鏈和借用構(gòu)造函數(shù)的缺陷,融合了他們的優(yōu)點(diǎn),成為JavaScript中最常用的繼承模式。而且instanceOf和isPrototype()也能夠識(shí)別基于組合繼承創(chuàng)建的對(duì)象。
### 3. 原型式繼承
借用原型可以基于已有的對(duì)象創(chuàng)建新對(duì)象,同時(shí)還不必因此創(chuàng)建自定義類型。
var person = { name:"Nicholas", friends:["Shelby","court","Van"] }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); alert(person.friends) //"Shelby,Count,Van,Rob,Barbie"
Object.create()傳遞第二個(gè)參數(shù)
var person = { name: "Nicholas", friends: ["Shelby","Court","Van"] } var anotherPerson = Object.create(person,{ name: { value: "Greg" } }); var anotherPerson2 = Object.create(person,{ name: { value: "blue" } }); alert(anotherPerson.name) //"Greg" alert(anotherPerson2.name) //"blue"
Obeject.create()方法IE9開(kāi)始兼容
### 4. 寄生式繼承
寄生式繼承的思路與寄生構(gòu)造函數(shù)和工廠模式類似,即創(chuàng)建一個(gè)僅用于封裝繼承過(guò)程的函數(shù),該函數(shù)在內(nèi)部以某種方式來(lái)增強(qiáng)對(duì)象,最后再像·真地是它做了所有工作一樣返回對(duì)象。
function createAnother(original) { var clone = object(original); clone.sayHi = function(){ alert("hi"); }; return clone; } var person = { name: "Nicholas", friends: ["Shelby","Court","Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"hi"
本文主要是個(gè)人摘自《javascript高級(jí)程序設(shè)計(jì)》用來(lái)做個(gè)人筆記的,請(qǐng)大佬們手下留情。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/106981.html
摘要:原型鏈實(shí)現(xiàn)繼承例子繼承了借用構(gòu)造函數(shù)基本思想在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類構(gòu)造函數(shù),通過(guò)使用和方法可以在新創(chuàng)建的對(duì)象上執(zhí)行構(gòu)造函數(shù)。 前言:大多OO語(yǔ)言都支持兩種繼承方式:接口繼承和實(shí)現(xiàn)繼承,而ECMAScript中無(wú)法實(shí)現(xiàn)接口繼承,ECMAScript只支持實(shí)現(xiàn)繼承,而且其實(shí)現(xiàn)繼承主要是依靠原型鏈來(lái)實(shí)現(xiàn)。 1.原型鏈 基本思想:利用原型讓一個(gè)引用類型繼承另外一個(gè)引用類型的屬性和方法。...
摘要:原型繼承缺點(diǎn)子類實(shí)例共享屬性,造成實(shí)例間的屬性會(huì)相互影響可以看到子類的實(shí)例屬性皆來(lái)自于父類的一個(gè)實(shí)例,即子類共享了同一個(gè)實(shí)例共享了父類的方法構(gòu)造函數(shù)繼承缺點(diǎn)父類的方法沒(méi)有被共享,造成內(nèi)存浪費(fèi)子實(shí)例的屬性都是相互獨(dú)立的實(shí)例方法也是獨(dú)立的,沒(méi)有 原型繼承 缺點(diǎn): 子類實(shí)例共享屬性,造成實(shí)例間的屬性會(huì)相互影響 function Parent1() { this.name = [super...
摘要:基于原型的繼承原型上的屬性被共享了不是我們所需要的這種繼承會(huì)有如下的缺點(diǎn)如果父類包含有引用類型的屬性所有的子類就會(huì)共享這個(gè)屬性。 基于原型的繼承 function father() { this.faName = father; this.names=[11,22] } father.prototype.getfaName = fun...
摘要:使用最多的繼承模式是組合繼承,這種模式使用原型鏈繼承共享的屬性和方法,而借用構(gòu)造函數(shù)繼承實(shí)例屬性。原型式繼承,可以在不必預(yù)先定義構(gòu)造函數(shù)的情況下實(shí)現(xiàn)繼承,其本質(zhì)是執(zhí)行給定對(duì)象的淺復(fù)制。 1、原型鏈實(shí)現(xiàn)繼承 function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = func...
摘要:使用關(guān)鍵字熟悉的同學(xué)應(yīng)該非常熟悉這個(gè)關(guān)鍵字,中的繼承都是靠它實(shí)現(xiàn)的。新加入的關(guān)鍵字是語(yǔ)法糖,本質(zhì)還是函數(shù)使用修改之前的例子,將會(huì)更簡(jiǎn)單在下面的例子,定義了一個(gè)名為的類,然后定義了一個(gè)繼承于的類。 使用Object.create實(shí)現(xiàn)類式繼承 下面是官網(wǎng)的一個(gè)例子 //Shape - superclass function Shape() { this.x = 0; this.y ...
閱讀 2625·2021-11-18 10:02
閱讀 2285·2021-09-30 09:47
閱讀 1782·2021-09-27 14:01
閱讀 3114·2021-08-16 11:00
閱讀 3168·2019-08-30 11:06
閱讀 2399·2019-08-29 17:29
閱讀 1539·2019-08-29 13:19
閱讀 451·2019-08-26 13:54