日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

JavaScript 常見的繼承方式匯總

瀏覽:145日期:2023-10-12 17:15:40

原型鏈機制:

在ECMAscript中描述了原型鏈的概念,并將原型鏈作為實現繼承的主要方法,其基本思想就是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。

構造函數和原型還有實例之間的關系:

每個構造函數都有一個原型對象(prototype),原型對象都包含一個指向構造函數的指針(constructor),而實例都包含一個指向原型對象的內部指針 ( __propto__ ) 。關系圖如下圖所示:

JavaScript 常見的繼承方式匯總

每一個Function都是Object基類的一個實例,所以每一個Function上都有一個__proto__指向了Object.prototype。

當查找一個實例的屬性時,會先從這個實例的自定義屬性上找,如果沒有的話通過__proto__去實例所屬類的原型上去找,如果還沒有的話再通過原型(原型也是對象,只要是對象就有__proto__屬性)的__proto__到Object的原型上去找,一級一級的找,如果沒有就undefined。

所以引用類型之間的繼承就是通過原型鏈機制實現的。

一.原型繼承

原型繼承:把父類的私有+公有的屬性和方法,都作為子類公有的屬性。

核心:不是把父類私有+公有的屬性克隆一份一模一樣的給子類的公有。他是通過__proto__建立和子類之間的原型鏈,當子類的實例需要使用父類的屬性和方法的時候,可以通過__proto__一級級找上去使用。 

function Parent(){ this.x = 199; this.y = 299;}Parent.prototype.say = function(){ console.log(’say’)}function Child(){ this.g = 90;}Child.prototype = new Parent();var p = new Parent();var c = new Child();console.dir(c)

實現的本質是重寫了原型對象 ,通過將子類的原型指向了父類的實例,所以子類的實例就可以通過__proto__訪問到 Child.prototype 也就是 Parent的實例,這樣就可以訪問到父類的私有方法。然后再通過__proto__指向父類的prototype就可以獲得到父類原型上的方法。

這樣就做到了將父類的私有、公有方法和屬性都當做子類的公有屬性。這樣就通過原型鏈實現了繼承。

但是別忘了默認的原型,因為所有引用類型都是繼承了Object的,所有說子類也可以訪問到Object上的方法如toString() 、valueOf() 等。

結果如下圖所示:

JavaScript 常見的繼承方式匯總

有的時候我們需要在子類中添加新的方法或者是重寫父類的方法時候,切記一定要放到替換原型的語句之后。

function Parent(){ this.x = 199; this.y = 299;}Parent.prototype.say = function(){ console.log(’say’)}function Child(){ this.g = 90;}/*Child.prototype.Bs = function(){ console.log(’Bs’)}*/在這里寫子類的原型方法和屬性是沒用的因為會改變原型的指向,所以應該放到重新指定之后Child.prototype = new Parent();Child.prototype.constructor=Child//由于重新修改了Child的原型導致默認原型上的constructor丟失,我們需要自己添加上,其實沒啥用,加不加都一樣Child.prototype.Bs = function(){ console.log(’Bs’)}Child.prototype.say = function(){ console.log(’之后改的’)}var p = new Parent();var c = new Child();console.dir(c)c.Bs() //Bsc.say() // 之后改的p.say() //say 不影響父類實例訪問父類的方法

存在的問題:

1. 子類繼承父類的屬性和方法是將父類的私有屬性和公有方法都作為自己的公有屬性和方法,我們要清楚一件事情就是我們操作基本數據類型的時候操作的是值,在操作應用數據類型的時候操作的是地址,如果說父類的私有屬性中引用類型的屬性,那他被子類繼承的時候會作為公有屬性,這樣子類一操作這個屬性的時候,會影響到子類二。

2. 在創建子類的實例時,不能向父類型的構造函數中傳遞參數。應該說是沒有辦法在不影響所有對象實例的情況下,給父類的構造函數傳遞參數。

所以在實際中很少單獨使用原型繼承。

二.call繼承

改變方法的this指向,同時執行方法。 在子類構造函數中父類.call(this) 可以將父類的私有變成子類的私有。

function Parent() { this.x = 100; this.y = 199;}Parent.prototype.fn = function() {} function Child() { this.d = 100; Parent.call(this); //構造函數中的this就是當前實例}var p = new Parent();var c = new Child();console.log(p) //Parent {x: 100, y: 199}console.log(c) //Child {d: 100, x: 100, y: 199}

在子類的構造函數中,改變父類的this指向,改變為子類的實例,同時運行父類方法,這樣父類中的this.x就變成了子類的實例.x ,通過這種方法就可以繼承了父類的私有屬性,且只能繼承父類的私有屬性和方法。

三.冒充對象繼承

冒充對象繼承的原理是循環遍歷父類實例,然后父類實例的私有方法全部拿過來添加給子類實例。

function Parent(){ this.x = 100;}Parent.prototype.getX = function(){ console.log(’getX’)}function Child(){ var p = new Parent(); for(var attr in p){//for in 可以遍歷到原型上的公有自定義屬性 this[attr] = p[attr] } //以下代碼是只獲得到私有方法和屬性,如果不加這個的話就可以遍歷到所有方法和屬性 /*if(e.hasOwnProperty(attr)){ this[attr] = e[attr] } e.propertyIsEnumerable()*///可枚舉屬性==> 可以拿出來一一列舉的屬性}var p = new Parent();var c = new Child();console.dir(c)

for in 可以遍歷到原型上的公有自定義屬性 ,所以他可以拿到私有和公有的屬性和方法,這個你可以遍歷私有和公有的,需要你加限制條件。但是如果不做hasOwnProperty判斷那么就是把父類的公有的和私有的都拿過來當私有的。

四.混合繼承

就是將call繼承和原型繼承集合在一起,無論是私有的還是公有的都拿過來了。但是有個問題就是子類的原型上的多了一套父類私有屬性,但是不會產生問題。因為子類的私有屬性也有一套相同的通過call繼承拿過來的。

function Parent(){ this.x=100;}Parent.prototype.getX = function(){}function Child(){ Parent.call(this);}Child.prototype = new Parent();Child.prototype.constructor = Child;var p = new Parent();var c = new Child();console.log(c)//Child {x: 100}

存在的問題:

無論在什么情況下,都會調用兩次構造函數:一次是在創建子類型原型的時候,另一次是在子類型構造函數的內部,沒錯,子類型最終會包含父類型對象的全部實例屬性,但我們不得不在調用子類構造函數時重寫這些屬性。

還有一種就是call+拷貝繼承

//混合繼承:call繼承+拷貝繼承 function extend(newEle,oldEle){ for(var attr in oldEle){ newEle[attr]=oldEle[attr]; } } function F(){ this.x=100; this.showX=function(){} } F.prototype.getX=function(){}; F.prototype.getX1=function(){}; var f1=new F; console.dir(f1) function S(){ F.call(this)//call繼承 } extend(S.prototype, F.prototype);//拷貝繼承 S.prototype.cc=function(){ } var p1=new S; console.dir(p1);

這種方式使用call繼承將父類的私有方法繼承過來,使用for in 拷貝將父類的公有屬性和方法繼承過來,比較實用。

五.中間件繼承

中間件繼承就是通過原型鏈的機制,子類的prototype.__proto__本來應該是直接指向Object.prototype。

從父類的原型上的__proto__也可以到Object.prototype,在父類.prototype上停留了下,父類.prototype就是一個中間件,所以子類可以繼承到父類的公有方法當做自己的公有方法。

function Parent(){ this.x = 100;}Parent.prototype.getX = function(){}function Child(){ }Child.prototype.__proto__ = Parent.prototype;var p = new Parent();var c = new Child()console.log(c)

六.寄生組合式繼承

   寄生式組合: call繼承+Object.create();

所謂寄生組合式繼承就是通過借用構造函數來繼承屬性,通過原型鏈的混合形式來繼承方法。

基本思路是不必為了指定子類的原型而調用父類的構造函數,我們所需要的就是父類型原型的一個副本。

本質上,就是使用寄生式繼承父類的原型,然后再將結果指定給子類的原型。

function F(){ this.x=100;}F.prototype.showX=function(){};function S(){ this.y = 200 F.call(this)//只繼承了私有的;}function inheritPrototype(subType,superType){ var prototype = Object.create(superType.prototype);//創建對象 prototype.constructor = subType;//增強對象 subType.prototype = prototype;//指定對象}inheritPrototype(S,F)var p1=new S;console.dir(p1)

1、第一步是創建父類型原型的一個副本。

2、第二步是為創建的副本增加constructor屬性,從而彌補了因為重寫原型而失去的默認的constructor屬性。

3、第三步是將創建的對象賦值給子類型的原型。

這個例子的高效率體現在他只調用了一次SuperType 構造函數,并且因此避免了在SubType.prototype上面創建不必要的、多余的屬性。與此同時原型鏈還能保持不變,所以可以正常使用instanceof 和 isPrototypeOf() ,所以寄生組合繼承是引用類型最理想的繼承方法。

七.class繼承

class 可以通過extends關鍵字實現繼承,這比 ES5 的通過修改原型鏈實現繼承,要清晰和方便很多。

class Father{ constructor(x, y) { this.x = x; this.y = y; } toString() { return ’(’ + this.x + ’, ’ + this.y + ’)’; }}class Son extends Father{ constructor(x,y,color){ super(x,y); // 調用父類的constructor(x, y) this.color = color; } toString() {console.log( super.toString()+this.color); // 調用父類的toString() }}let son = new Son(3,4,’red’);son.toString();//結果為(3,4)red

上面代碼定義了一個Son類,該類通過extends關鍵字,繼承了Father類的所有屬性和方法。

上面代碼中,constructor方法和toString方法之中,都出現了super關鍵字,它在這里表示父類的構造函數,用來新建父類的this對象。

子類必須在constructor方法中調用super方法,否則新建實例時會報錯。這是因為子類自己的this對象,必須先通過父類的構造函數完成塑造,得到與父類同樣的實例屬性和方法,然后再對其進行加工,加上子類自己的實例屬性和方法。如果不調用super方法,子類就得不到this對象。

以上就是JavaScript 常見的繼承方式匯總的詳細內容,更多關于JavaScript 繼承方式的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
91一区二区三区四区| 国产精品亚洲欧美一级在线| 久久中文欧美| 国产精品免费大片| 欧美精品国产一区| 国产日韩欧美一区在线| 一区二区91| 在线精品亚洲| 日韩国产高清在线| 日韩动漫一区| 久久久精品国产**网站| 国产91在线播放精品| 国产一区二区三区亚洲综合| 大香伊人久久精品一区二区 | 在线精品视频在线观看高清| 久久精品不卡| 亚洲综合精品四区| 视频一区二区国产| 日日夜夜免费精品| 日韩精品欧美大片| 欧美日韩夜夜| 粉嫩av一区二区三区四区五区| 成人福利av| 亚洲一级高清| 美美哒免费高清在线观看视频一区二区| 在线免费观看亚洲| 国产精品美女在线观看直播| 91亚洲国产高清| 欧美在线影院| 日韩精品视频在线看| 精品亚洲成人| 九九精品调教| 亚洲性视频在线| 久久免费视频66| 神马午夜在线视频| 亚洲激情中文| 欧美日韩18| 国产精品成人一区二区不卡| 免费国产自久久久久三四区久久 | 日韩精品一卡| 视频一区二区中文字幕| 国产欧美日韩精品高清二区综合区| 国产一区丝袜| 香蕉视频成人在线观看| 国产精品男女| 婷婷色综合网| 国产精品白浆| 成人av动漫在线观看| 日韩专区视频网站| 日本久久精品| 亚洲三级毛片| av高清不卡| 色综合视频一区二区三区日韩| 国产一区调教| 亚洲精品美女91| 国产成人精品一区二区三区在线| 日韩午夜电影| 久久精品免费看| 蜜桃视频免费观看一区| www在线观看黄色| 日韩1区2区3区| 久久久久国产一区二区| 国产亚洲欧美日韩在线观看一区二区| 亚洲美女久久精品| 婷婷综合电影| 国内亚洲精品| 精品三区视频| 亚久久调教视频| 成人久久一区| 久久av影视| 国产一级一区二区| 亚洲精品影院在线观看| 香蕉久久国产| se01亚洲视频 | 亚洲午夜一级| 国产日韩欧美一区二区三区 | 91成人福利| 欧美日韩1区| 99国产精品视频免费观看一公开 | 久久国产88| а√天堂8资源在线| 欧美视频一区| 爽好多水快深点欧美视频| 伊人网在线播放| 日韩高清电影免费| 99视频一区| 日韩精品麻豆| 麻豆久久久久久| 日韩中文字幕视频网| 在线亚洲成人| 亚洲一级黄色| 另类中文字幕国产精品| 国产伦精品一区二区三区千人斩| 在线亚洲一区| 国产日韩精品视频一区二区三区| 国产一区清纯| 午夜久久黄色| 午夜在线观看免费一区| 视频一区欧美日韩| 午夜精品影视国产一区在线麻豆| 亚洲欧洲日韩| 亚洲精品高潮| 欧美日韩18| 久久精品天堂| 国产综合色区在线观看| 米奇777超碰欧美日韩亚洲| 最新亚洲激情| 合欧美一区二区三区| 亚洲欧美日本国产专区一区| 蜜桃视频一区二区三区在线观看| 亚洲天堂免费| 青青草国产精品亚洲专区无| 国产精品亚洲四区在线观看 | 午夜久久tv| 一区二区国产在线观看| 欧美在线不卡| 国产精品日韩精品在线播放| 久久精品国产成人一区二区三区| 国产一区二区三区久久| 亚洲午夜天堂| 好吊一区二区三区| 青青国产精品| 精品视频亚洲| 99热精品久久| 亚洲天堂免费| 麻豆精品国产91久久久久久| 久久男人天堂| 夜久久久久久| 青青草视频一区| 高清不卡亚洲| 鲁大师成人一区二区三区| 日韩毛片网站| 精品国产美女a久久9999| 久久精品青草| 国产一级久久| 国产精品一区二区三区av麻| 色一区二区三区| 视频一区视频二区中文| 国产精品v亚洲精品v日韩精品| 欧美日韩国产v| 只有精品亚洲| 福利视频一区| 亚洲免费中文| 麻豆精品少妇| 亚洲一区二区动漫| 国产精品视频一区二区三区 | 国产精品igao视频网网址不卡日韩| аⅴ资源天堂资源库在线| 亚洲精品在线观看91| 国产欧美丝祙| 999国产精品999久久久久久| 亚洲精品免费观看| 在线看片国产福利你懂的| 亚洲一区久久| 久久久久久久久成人| jiujiure精品视频播放| 国产精品一区二区三区美女| 不卡一区综合视频| 国产精品对白| 亚洲黄色影院| 你懂的网址国产 欧美| 黑丝美女一区二区| 国产精品久久久一区二区| 99精品在线| 欧美日韩一区二区三区四区在线观看| 99视频精品全国免费| 国产乱码精品一区二区亚洲| 亚洲国产综合在线看不卡| 国产剧情一区| 欧美精品一区二区三区精品| 国产乱码精品一区二区三区四区 | 亚洲精选91| 亚洲综合电影| 国产欧美88| 三级在线观看一区二区| 国产 日韩 欧美 综合 一区| 亚洲网址在线观看| 久久婷婷av| 国产精品99久久免费| 免费视频一区二区| 欧洲一级精品| 国产精品超碰| 免费人成在线不卡| 日韩精品永久网址| 国产精品对白| 亚欧洲精品视频在线观看| 99精品电影| 成人国产精品一区二区免费麻豆| 视频一区中文字幕精品| 欧美特黄一级大片| 精品久久国产一区| 天堂av一区| 亚洲免费影视| 欧美日韩中文一区二区| 国产成人精品一区二区三区免费 | 久久一区精品| 亚洲精品激情| 亚洲欧美久久| 日韩精品看片| 精品网站999|