摘要:通過方法或方法也可以,實質(zhì)上是在未來將要新創(chuàng)建的實例的環(huán)境下調(diào)用構(gòu)造函數(shù)。組合繼承指的是將原型鏈繼承和借用構(gòu)造函數(shù)繼承的技術(shù)組合到一塊,從而發(fā)揮二者之長的一種繼承模式。該模式通過借用構(gòu)造函數(shù)繼承屬性,通過重新子類型繼承方法。
原型鏈繼承
function SuperType() { this.property = true; } // 在原型鏈上定義方法。 SuperType.prototype.getSuperValue = function (){ return this.property; } function SubType() { this.subproperty = false; } // 替換SubType原型,達到繼承效果。 SubType.prototype = new SuperType(); // 開始寫SubType的方法,注:SubType的方法必須寫在替換SubType原型語句后 SubType.prototype.getSubValue = function (){ return this.subproperty; } var instance = new SubType(); alert(instance.getSuperValue());
原型鏈繼承的原理如期名,是利用創(chuàng)建父類(SuperType)的實例,并將該實例賦值給子類(SubType).prototype實現(xiàn)的,實質(zhì)是重寫子類的原型對象。
原型鏈繼承特點:
引用類型值的原型屬性會被所有實例共享。
在創(chuàng)建子類型的實例時,沒辦法再不影響所有對象實例的情況下向超類傳遞參數(shù)。
即實現(xiàn)所有屬性方法共享,但無法做到屬性、方法獨享。
借用構(gòu)造函數(shù)繼承function SuperType() { this.colors = ["red","blue","green"]; } function SubType() { //繼承屬性 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
借用構(gòu)造函數(shù)繼承(constructor stealing),該繼承思想很簡單,即在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù)即可。通過call()方法(或apply()方法也可以),實質(zhì)上是在(未來將要)新創(chuàng)建的SubType實例的環(huán)境下調(diào)用SuperType構(gòu)造函數(shù)。
借用構(gòu)造函數(shù)繼承特點:
可以在子類型構(gòu)造函數(shù)中向超類型構(gòu)造函數(shù)傳遞參數(shù)。
方法都在構(gòu)造函數(shù)中定義,無法實現(xiàn)函數(shù)復(fù)用。
超類型的原型中定義的方法對子類不可見。
即實現(xiàn)所有屬性獨享,但無法做到方法繼承。
組合繼承function 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.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); } var instance1 = new SubType("Y",21); instance1.colors.push("black"); alert(instance1.colors); //red,blue,green,black instance1.sayName(); //Y instance1.sayAge(); //21 var instance2 = new SubType("Z",22); alert(instance2.colors); //red,blue,green instance2.sayName(); //Z instance2.sayAge(); //22
組合繼承(combination inheritance)又叫偽經(jīng)典繼承,是JavaScript中最常用的繼承模式。組合繼承指的是將原型鏈繼承和借用構(gòu)造函數(shù)繼承的技術(shù)組合到一塊,從而發(fā)揮二者之長的一種繼承模式。該模式通過借用構(gòu)造函數(shù)繼承屬性,通過重新子類型prototype繼承方法。
組合繼承特點:
實現(xiàn)了所有方法共享,屬性獨享。
instanceof()和isprototypeOf()能夠識別基于組合繼承創(chuàng)建的對象。
實現(xiàn)的時候調(diào)用了兩次超類(父類),產(chǎn)生多余屬性。
原型式繼承// 工具函數(shù),實質(zhì)是對傳入的對象執(zhí)行一次淺拷貝。 function object(o) { function F() {} F.prototype = o; return new F(); } var person = { name:"Y", friends:["S","C","V"], say:function () { alert(this.friends); } }; var anotherPerson = object(person); anotherPerson.name = "G"; anotherPerson.friends.push("R"); var yetAnotherPerson = object(person); yetAnotherPerson.name = "L"; yetAnotherPerson.friends.push("B"); person.friends.push("my"); anotherPerson.say(); //S,C,V,R,B,my alert(person.friends); //S,C,V,R,B,my
原型式繼承是由道格拉斯·克羅克福德提出的,該模式要求你必須有一個對象可以作為另外一個對象的基礎(chǔ)。該模式將一個對象傳遞給object()函數(shù),然后再根據(jù)具體需求對得到的對象加以修改即可。
原型式繼承特點:
以傳入object的對象為原型,拷貝一個副本并反回。
做不到函數(shù)復(fù)用,導(dǎo)致效率低。
對象的引用類型所有實例共享(person的引用類型friends不僅屬于person所有,而且也會被antherPerson和yetAnotherPerson共享)。
寄生式繼承function object(o) { function F() {} F.prototype = o; return new F(); } function createAnother(original) { var clone = object(original); clone.sayHi = function (){ alert(this.friends); }; return clone; } var person = { name:"Y", friends:["S","C","V"] }; var anotherPerson = createAnother(person); anotherPerson.friends.push("test"); anotherPerson.sayHi(); var anotherPerson2 = createAnother(person); anotherPerson2.sayHi();
寄生式繼承(parasitic)同樣是由克羅克福德提出并推廣而之的。該模式創(chuàng)建一個僅用于封裝繼承過程的函數(shù),該函數(shù)的內(nèi)部以某種方式增強對象,最后再像真地式它做了所有工作一樣返回對象。
寄生式繼承特點:
做不到函數(shù)復(fù)用,導(dǎo)致效率低。
對象的引用類型所有實例共享。
寄生組合式繼承function object(o) { function F() {} F.prototype = o; return new F(); } // 將超類型的prototype淺拷貝一遍并賦值給子類型的prototype // (相當于利用超類型prototype重寫子類型prototype以達到繼承效果) function inheritPrototype(subType,superType) { var prototype = object(superType.prototype); prototype.constructor = subType; subType.prototype = prototype; } function 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); this.age = age; } //繼承方法 inheritPrototype(SubType,SuperType); SubType.prototype.sayAge = function(){ alert(this.age); } var instance1 = new SubType("Y",21); instance1.colors.push("black"); alert(instance1.colors); //red,blue,green,black instance1.sayName(); //Y instance1.sayAge(); //21 var instance2 = new SubType("Z",22); alert(instance2.colors); //red,blue,green instance2.sayName(); //Z instance2.sayAge(); //22
原理如圖:
寄生組合式繼承解決了組合繼承最大的問題——無論什么情況下,都會調(diào)用兩次超類型構(gòu)造函數(shù)。該模式思路是:不必為了指定子類型的原型而調(diào)用超類型的構(gòu)造函數(shù),我們所需的無非就是超類型原型的副本而已。本質(zhì)上,就是使用寄生式繼承來繼承超類型的原型,然后再將結(jié)果指定給子類型的原型。
寄生組合式繼承特點:
實現(xiàn)了所有方法共享,屬性獨享。
instanceof()和isprototypeOf()能夠識別基于組合繼承創(chuàng)建的對象。
參考自《JavaScript高級程序設(shè)計》
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/108997.html
摘要:這正是我們想要的太棒了毫不意外的,這種繼承的方式被稱為構(gòu)造函數(shù)繼承,在中是一種關(guān)鍵的實現(xiàn)的繼承方法,相信你已經(jīng)很好的掌握了。 你應(yīng)該知道,JavaScript是一門基于原型鏈的語言,而我們今天的主題 -- 繼承就和原型鏈這一概念息息相關(guān)。甚至可以說,所謂的原型鏈就是一條繼承鏈。有些困惑了嗎?接著看下去吧。 一、構(gòu)造函數(shù),原型屬性與實例對象 要搞清楚如何在JavaScript中實現(xiàn)繼承,...
摘要:中的繼承并不是明確規(guī)定的,而是通過模仿實現(xiàn)的。繼承中的繼承又稱模擬類繼承。將函數(shù)抽離到全局對象中,函數(shù)內(nèi)部直接通過作用域鏈查找函數(shù)。這種范式編程是基于作用域鏈,與前面講的繼承是基于原型鏈的本質(zhì)區(qū)別是屬性查找方式的不同。 這一節(jié)梳理對象的繼承。 我們主要使用繼承來實現(xiàn)代碼的抽象和代碼的復(fù)用,在應(yīng)用層實現(xiàn)功能的封裝。 javascript 的對象繼承方式真的是百花齊放,屬性繼承、原型繼承、...
摘要:繼承前言作為一門輕量級的腳本語言在和的橫空出世之后將其推向的新的高度雖然中出現(xiàn)的新的生成對象的類語法格式但依然為的語法糖而我們依然有必要從的原生實現(xiàn)入手來了解它的繼承實現(xiàn)方式給出了更加簡潔的固定的類聲明方式有興趣的可以查看阮一峰的入門下面給 javascript繼承 前言 javascript作為一門輕量級的腳本語言在ES6和node.js的橫空出世之后將其推向的新的高度,雖然 ES6...
摘要:我們有了構(gòu)造函數(shù)之后,第二步開始使用它構(gòu)造一個函數(shù)。來個例子這種方式很簡單也很直接,你在構(gòu)造函數(shù)的原型上定義方法,那么用該構(gòu)造函數(shù)實例化出來的對象都可以通過原型繼承鏈訪問到定義在構(gòu)造函數(shù)原型上的方法。 來源: 個人博客 白話解釋 Javascript 原型繼承(prototype inheritance) 什么是繼承? 學過面向?qū)ο蟮耐瑢W們是否還記得,老師整天掛在嘴邊的面向?qū)ο笕筇?..
摘要:和構(gòu)造函數(shù)前面提到,是個內(nèi)置隱藏屬性,雖然在可以通過訪問,但是其設(shè)計本意是不可被讀取和修改的,那么我們?nèi)绾卫迷玩渷斫⒗^承關(guān)系提供了關(guān)鍵字。到這兒,思路就清晰了,怎么讓對象和對象的相連實現(xiàn)繼承只需把的構(gòu)造函數(shù)的連接到就行了。 什么是繼承? 大多數(shù)人使用繼承不外乎是為了獲得這兩點好處,代碼的抽象和代碼的復(fù)用。代碼的抽象就不用說了,交通工具和汽車這類的例子數(shù)不勝數(shù),在傳統(tǒng)的OO語言中(...
閱讀 3431·2021-11-15 11:39
閱讀 1579·2021-09-22 10:02
閱讀 1323·2021-08-27 16:24
閱讀 3609·2019-08-30 15:52
閱讀 3432·2019-08-29 16:20
閱讀 835·2019-08-28 18:12
閱讀 563·2019-08-26 18:27
閱讀 731·2019-08-26 13:32