摘要:例如假如定義第二個子類然后在第一個子類中重新定義方法最后的輸出結(jié)果是由此可以看出,中的方法也發(fā)生了改變,如果將替換成方法,就不會存在這樣的問題。
前言
最近一直在回顧js繼承方式,在閱讀《高級程序設(shè)計》第3版 的時候遇到一個問題,下面僅個人看法,如果有理解錯誤或者不同看法,歡迎一起探討:
正文何謂寄生組合繼承,實質(zhì)上分為兩步:
將父類的原型對象賦值給子類的原型對象
將子類原型對象中的constructor指針指向子類構(gòu)造函數(shù)
這樣就實現(xiàn)了繼承,具體代碼如下所示(書中原代碼):
function SuperType(name){ this.name = name; } SuperType.prototype.sayName = function(){ console.log(this.name); } function SubType(name, age){ SuperType.call(this, name); this.age = age; } function inheritPrototype(subType, superType){ const subPrototype = Object(superType.prototype); subPrototype.constructor = SubType; subType.prototype = subPrototype; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ console.log(this.age); } const sub_1 = new SubType("liumin", "23"); sub_1.sayName(); sub_1.sayAge();
在inheritPrototype函數(shù)當(dāng)中正是完成了上面的兩個步驟,但是注意這里是通過Object函數(shù)創(chuàng)建一個對象賦值給subPrototype的,接下來我們了解一下Object函數(shù)
Object函數(shù)為給定值創(chuàng)建一個對象包裝器,如果傳入的是undefined 或者 null,則返回一個空對象;否則返回一個給定值對應(yīng)類型的對象;
console.log(Object(undefined)); console.log(Object(null)); console.log(Object("123")); console.log(Object(123));
輸出結(jié)果是:
如果傳入的參數(shù)是一個對象,那么通過Object返回的則是對這個對象的引用,如下所示:
const person = { name:"xiaohong", age:"23", grade:"12", } const anotherPerson = Object(person); console.log(anotherPerson === person);
輸出結(jié)果:
person和anotherPerson引用的是同一塊內(nèi)存地址,這與Object.create(obj)是有差別的,Object.create(obj)是在內(nèi)存中新開辟一個空間
如果在上述的繼承方式中存在一個問題,如果之后通過子類的原型對象對父類中的sayName方法進行重新定義,這時候就會修改父類中的sayName方法,從而繼承父類的其他子類中的sayName方法也就會被篡改掉,造成混亂。
例如:
假如定義第二個子類——SubTypeCopy:
function SubTypeCopy(name, height){ SuperType.call(this, name); this.height = height; } inheritPrototype(SubTypeCopy, SuperType);
然后在第一個子類中重新定義sayName方法:
SubType.prototype.sayName = function(){ console.log(`my name is:${this.name}`); } const sub_1 = new SubType("liumin", "23"); const sub_2 = new SubTypeCopy("liujie","180"); sub_1.sayName(); sub_2.sayName();
最后的輸出結(jié)果是:
由此可以看出,SubTypeCopy中的sayName方法也發(fā)生了改變,如果將Object替換成Object.create(obj)方法,就不會存在這樣的問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/94824.html
摘要:下面來看一個例子繼承屬性繼承方法在這個例子中構(gòu)造函數(shù)定義了兩個屬性和。組合繼承最大的問題就是無論什么情況下都會調(diào)用兩次超類型構(gòu)造函數(shù)一次是在創(chuàng)建子類型原型的時候另一次是在子類型構(gòu)造函數(shù)內(nèi)部。 組合繼承 組合繼承(combination inheritance),有時候也叫做偽經(jīng)典繼承,指的是將原型鏈和借用構(gòu)造函數(shù)的技術(shù)組合到一塊,從而發(fā)揮二者之長的一種繼承模式。其背后的思路是使用原型鏈...
摘要:高程第六章繼承理解與實踐昨日細細的讀了一遍高程現(xiàn)在寫篇文章來鞏固下認知吧讀首先是從中讀到了什么我自己也在讀書的時候用筆記下了各個部分的點現(xiàn)在等于閱讀筆記回憶下書本理解基礎(chǔ)第五版中規(guī)定了兩種屬性數(shù)據(jù)屬性訪問器屬性數(shù)據(jù)屬性包含一個數(shù)據(jù)值的位 JavaScript高程第六章:繼承-理解與實踐昨日細細的讀了一遍JavaScript高程,現(xiàn)在寫篇文章來鞏固下認知吧. 讀 首先是從中讀到了什么,我...
摘要:高程讀書筆記第六章理解對象創(chuàng)建自定義對象的方式有創(chuàng)建一個實例,然后為它添加屬性和方法。創(chuàng)建了自定義的構(gòu)造函數(shù)之后,其原型對象默認只會取得屬性至于其他方法都是從繼承而來的。 JS高程讀書筆記--第六章 理解對象 創(chuàng)建自定義對象的方式有創(chuàng)建一個Object實例,然后為它添加屬性和方法。還可用創(chuàng)建對象字面量的方式 屬性類型 ECMAScript在定義只有內(nèi)部采用的特性時,描述了屬性的各種特征...
摘要:由構(gòu)造函數(shù)返回的對象就是表達式的結(jié)果。如果構(gòu)造函數(shù)沒有顯式返回一個對象,則使用步驟創(chuàng)建的對象。運算符返回一個布爾值,表示對象是否為某個構(gòu)造函數(shù)的實例。 面向?qū)ο?本人能力有限,有誤請斧正 本文旨在復(fù)習(xí)面向?qū)ο?不包含es6) 本文學(xué)習(xí)思維 創(chuàng)建對象的方式,獲取對象屬性 構(gòu)造函數(shù),構(gòu)造函數(shù)的new 做了什么 原型與原型對象 原型鏈 繼承(借用構(gòu)造繼承、原型繼承、組合繼承、寄生組合繼承)...
摘要:對于采用這種模式的對象,還可以使用操作符確定它的類型寄生構(gòu)造函數(shù)模式通常,在前述的幾種模式都不適用的情況下,可以使用寄生構(gòu)造函數(shù)模式。這個模式可以在特殊的情況下用來為對象創(chuàng)建構(gòu)造函數(shù)。 ECMA-262把對象定義為:無序?qū)傩缘募希鋵傩钥梢园局怠ο蠡蛘吆瘮?shù)。嚴(yán)格來講,這就相當(dāng)于說對象是一組沒有特定順序的值。 1 理解對象 創(chuàng)建對象: var person = new Obje...
閱讀 3069·2021-11-24 11:14
閱讀 3480·2021-11-22 15:22
閱讀 3200·2021-09-27 13:36
閱讀 712·2021-08-31 14:29
閱讀 1328·2019-08-30 15:55
閱讀 1752·2019-08-29 17:29
閱讀 1143·2019-08-29 16:24
閱讀 2400·2019-08-26 13:48