亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

史上最為詳細(xì)的javascript繼承(推薦)

 更新時(shí)間:2019年05月18日 09:29:22   作者:zhangfaliang  
這篇文章主要介紹了javascript繼承,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

為大家分享js中最常見(jiàn)最詳細(xì)的繼承方式,接下來(lái)將一下面的幾個(gè)維度進(jìn)行展示說(shuō)明
文章有點(diǎn)長(zhǎng),請(qǐng)耐心閱讀😁,有什么錯(cuò)誤理解的地方希望留言指出來(lái)

  1. 產(chǎn)生原因
  2. 代碼實(shí)現(xiàn)
  3. 基本原理
  4. 語(yǔ)言實(shí)現(xiàn)
  5. 場(chǎng)景優(yōu)點(diǎn)
  6. 缺點(diǎn)

繼承方式

  1. 原型鏈繼承
  2. 借用構(gòu)造函數(shù)模式繼承
  3. 組合繼承
  4. 原型式繼承
  5. 寄生式繼承
  6. 寄生組合

原型鏈繼承
相信小伙伴們都知道到原型鏈繼承(ECMAScript 中描述了原型鏈的概念,并將原型鏈作為實(shí)現(xiàn)繼承的主要方法),因?yàn)樵玩溊^承非常的強(qiáng)大,但是也有它的缺點(diǎn),接下來(lái)咱們就按照上面的維度看看原型鏈繼承到底是什么鬼
代碼實(shí)現(xiàn):(需要兩個(gè)構(gòu)造函數(shù)來(lái)完成一個(gè)原型鏈繼承)

 // SuperType 構(gòu)造函數(shù)稱為超類
 function SuperType (){
   this.name='super';
   this.friend=[];
   this.property = true; 
}
SuperType.prototype.getName=function(){
  return this.name;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
}; 
// SubType 構(gòu)造函數(shù)稱為子類
function SubType(name,age){
  this.name=name;
  this.age=age;
  this.subproperty = false; 
}
SubType.prototype=new SuperType();
SubType.prototype.constrcutor=SubType;
SubType.prototype.getAge=function(){
  return this.age;
}
SubType.prototype.getSubValue = function (){
 return this.subproperty;
}; 
var child = new SubType('shiny',12);
console.log(child.getName)//shiny
console.log(child.getAge())//12

圖解部分 屬性

基本原理

使用類似作用域的原型鏈,進(jìn)行繼承查找

語(yǔ)言實(shí)現(xiàn)

定義兩個(gè)構(gòu)造函數(shù),分別為父類(SuperType)、子類(SubType),為了實(shí)現(xiàn)子類能夠使用父類的屬性(本身和原型上面的屬性)。重寫(xiě)子類的原型,讓子類的原型指向父類實(shí)例,這樣子類的構(gòu)造函數(shù)就是父類的實(shí)例地址,實(shí)現(xiàn)子類可以使用父類的本身和原型上的屬性

優(yōu)點(diǎn)

子類可以通過(guò)原型鏈的查找,實(shí)現(xiàn)父類的屬性公用與子類的實(shí)例

缺點(diǎn)  

  1. 一些引用數(shù)據(jù)操作的時(shí)候會(huì)出問(wèn)題,兩個(gè)實(shí)例會(huì)公用繼承實(shí)例的引用數(shù)據(jù)類
  2. 謹(jǐn)慎定義方法,以免定義方法也繼承對(duì)象原型的方法重名
  3. 無(wú)法直接給父級(jí)構(gòu)造函數(shù)使用參數(shù)

借用構(gòu)造函數(shù)模式繼承
雖然原型鏈繼承很強(qiáng)大但是也有他的缺點(diǎn),借用構(gòu)造函數(shù)繼承可以解決原型鏈繼承的缺點(diǎn),開(kāi)線面的解釋
代碼實(shí)現(xiàn):

// 把父類當(dāng)中一個(gè)函數(shù)使用
function SuperType(name){
this.name=name
this.friend=['a','b']
}
SuperType.prototype.getFriend=function(){
 return this.firend
}
function SubType(name){
 // 執(zhí)行父類函數(shù)
 SuperType.call(this,name);
}
var child = new SubType('shiny')
var childRed = new SubType('red')
console.log(child.name)//shiny
console.log(childRed.name)//red
child.firend.push('c')
console.log(child.friend)//a,b,c
console.log(childRed.friend)//a,b
console.log(childRed.getFriend)//undefined

基本原理

使用call apply方法,通過(guò)執(zhí)行方法修改tihs (上下文),是的父級(jí)的this變成子類實(shí)例的this,這樣每個(gè)實(shí)例都會(huì)得到父類的屬性,實(shí)現(xiàn)引用屬性備份

使用場(chǎng)景

父類中需要一些子類使用共享的引用類型,并且子類可能會(huì)操作父類共享的引用類型
但是父類的非this綁定的屬性和方法是不可以使用的(放在父類prototype的屬性和方法)

語(yǔ)言實(shí)現(xiàn)

不要把父類當(dāng)中構(gòu)造函數(shù),當(dāng)中一個(gè)函數(shù)來(lái)處理這樣更容易理解,在子類的構(gòu)造函數(shù)中借用父類函數(shù)通過(guò)修改this來(lái)執(zhí)行,這樣子類的實(shí)例包含父類的屬性

優(yōu)點(diǎn)

  1. 解決了原型鏈繼承的 引用類型操作問(wèn)題
  2. 解決了父類傳遞參數(shù)問(wèn)題

缺點(diǎn)

  1. 僅僅使用借用構(gòu)造函數(shù)模式繼承,無(wú)法擺脫夠著函數(shù)。方法在構(gòu)造函數(shù)中定義復(fù)用不可談
  2. 對(duì)于超類的原型定義的方法對(duì)于子類是不可使用的,子類的實(shí)例只是得到了父類的this綁定的屬性
  3. 考慮到這些缺點(diǎn),單獨(dú)使用借用構(gòu)造函數(shù)也是很少使用的

組合繼承

上面的兩種繼承方式(原型鏈繼承+借用構(gòu)造函數(shù)繼承),都有自己優(yōu)缺點(diǎn),但是他們不是很完美,下面解釋一下組合繼承

代碼實(shí)現(xiàn):

 

function SuperType(name){
  this.name=name;
  this.firend=['a','b']
}
SuperType.prototype.getName=function(){
  return this.name
}
function SubType(name,age){
  this.age=age;
  SuperType.call(this,name)
}
SubType.prototype=new SuperType();
SubType.prototype.constrcutor = SubType;
SubType.prototype.getAge=function(){
  return this.age
}
var childShiny=new SubType('shiny',23);
var childRed = new SubType('red',22);
childShiny.firend.push('c');
childRed.firend.push('d');
console.log(childShiny.getName());
console.log(childShiny.getAge());
console.log(childRed.getName());
console.log(childRed.getAge());
console.log(childRed.friend);//[a,b,d]
console.log(childShiny.friend);//[a,b,c]

 基本原理

使用原型鏈的繼承實(shí)現(xiàn),通過(guò)原型查找功能來(lái)滿足原型鏈共享方法
使用借用構(gòu)造函數(shù)方法,使用實(shí)例備份父類共享引用類型備份

使用場(chǎng)景

得到原型鏈繼承和構(gòu)造函數(shù)繼承的優(yōu)點(diǎn),是被開(kāi)發(fā)人員認(rèn)可的一種繼承方式,但是也有他的缺點(diǎn)
語(yǔ)言實(shí)現(xiàn)

定義兩個(gè)構(gòu)造函數(shù),分別為父類(SuperType)、子類(SubType),為了實(shí)現(xiàn)子類能夠使用父類的屬性(本身和原型上面的屬性)。重寫(xiě)子類的原型,讓子類的原型指向父類實(shí)例,這樣子類的構(gòu)造函數(shù)就是父類的實(shí)例地址,實(shí)現(xiàn)子類可以使用父類的本身和原型上的屬性
不要把父類當(dāng)中構(gòu)造函數(shù),當(dāng)中一個(gè)函數(shù)來(lái)處理這樣更容易理解,在子類的構(gòu)造函數(shù)中借用父類函數(shù)通過(guò)修改this來(lái)執(zhí)行,這樣子類的實(shí)例包含父類的屬性

優(yōu)點(diǎn)

  1. 解決了原型鏈繼承引用類型的實(shí)例操作導(dǎo)致引用改變
  2. 解決了借構(gòu)造函數(shù)繼承方式的,父類原型子類實(shí)例可以使用

缺點(diǎn)

  1. 父類的構(gòu)造函數(shù)被實(shí)例換了兩次
  2. 實(shí)例會(huì)有父類的構(gòu)造函數(shù)的一些this屬性、子類的構(gòu)造函數(shù)(prototype)上也有一份實(shí)例的上有的屬性

原型式繼承

話說(shuō)上面的的組合繼承不是已經(jīng)被開(kāi)發(fā)者認(rèn)可了嗎,原型式繼承是啥?下面咱們看看原型式繼承是什么樣的。

代碼實(shí)現(xiàn):

1 function object(o){
 function F(){};
 F.prototype=o;
  return new F()
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var personShiny = object(person);
var personRed = object(person);
console.log(personShiny.name)//Nicholas
console.log(personRed.name)//Nicholas
personShiny.friends.push('red');
personRed.friends.push('shiny');
console.log(personShiny.friends)//["Shelby", "Court", "Van","red","shiny"]
//ECMAScript 5 通過(guò)新增 Object.create()方法規(guī)范化了原型式繼承。這個(gè)方法接收兩個(gè)參數(shù):一
//個(gè)用作新對(duì)象原型的對(duì)象和(可選的)一個(gè)為新對(duì)象定義額外屬性的對(duì)象。在傳入一個(gè)參數(shù)的情況下,
//Object.create()與 object()方法的行為相同。
2 
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var personShiny = Object.create(person);
var personRed = Object.create(person);
console.log(personShiny.name)//Nicholas
console.log(personRed.name)//Nicholas
personShiny.friends.push('red');
personRed.friends.push('shiny');
console.log(personShiny.friends)//["Shelby", "Court", "Van","red","shiny"]

基本原理

通過(guò)Object.create()方法來(lái)創(chuàng)建一個(gè)有基礎(chǔ)類的實(shí)例,這實(shí)例的__proto__指向基礎(chǔ)類

使用場(chǎng)景

在不使用構(gòu)造函數(shù)的情況下,只想讓一個(gè)對(duì)象與另一個(gè)對(duì)象保持類似的情況下

語(yǔ)言實(shí)現(xiàn)

需要?jiǎng)?chuàng)建一個(gè)基礎(chǔ)對(duì)象,作為一個(gè)新對(duì)象的基礎(chǔ)對(duì)象,通過(guò)object方法或者Object.create方法處理得到一個(gè)新實(shí)例,這個(gè)新實(shí)例上的__proto__指向基礎(chǔ)對(duì)象

優(yōu)點(diǎn)

再不用創(chuàng)建構(gòu)造函數(shù)的情況下,實(shí)現(xiàn)了原型鏈繼承,代碼量減少一部分

缺點(diǎn)

  1. 一些引用數(shù)據(jù)操作的時(shí)候會(huì)出問(wèn)題,兩個(gè)實(shí)例會(huì)公用繼承實(shí)例的引用數(shù)據(jù)類
  2. 謹(jǐn)慎定義方法,以免定義方法也繼承對(duì)象原型的方法重名
  3. 無(wú)法直接給父級(jí)構(gòu)造函數(shù)使用參數(shù)

寄生繼承

咱們看了上面的原型式繼承,其實(shí)就是和原型鏈繼承差別不大,只是省去了構(gòu)造函數(shù)這一部,但是原型式繼承也是有缺點(diǎn)的(不能夠給備份的對(duì)象添加屬性),下面寄生繼承來(lái)解決。

代碼實(shí)現(xiàn):

// 和工廠模式非常類似,創(chuàng)建一個(gè)對(duì)象,增強(qiáng)一些功能并返回該對(duì)象
function createAnother(o){
  var clone = Object(o);
  clone.sayHi=function(){
   console.log('hi')
}
  return clone
}
var person = {
  name:'shiny',
  friends:['a','b']
}
var personShiny = createAnother(person);
console.log(personShiny.sayHi())//Ho

基本原理

備份一個(gè)對(duì)象,然后給備份的對(duì)象進(jìn)行屬性添加,并返回

使用場(chǎng)景

在考不使用構(gòu)造函數(shù)的情況下實(shí)現(xiàn)繼承,前面示
范繼承模式時(shí)使用的 object()函數(shù)不是必需的;任何能夠返回新對(duì)象的函數(shù)都適用于此模式

語(yǔ)言實(shí)現(xiàn)

類似構(gòu)造函數(shù),通過(guò)一個(gè)執(zhí)行方法,里面創(chuàng)建一個(gè)對(duì)象,為該對(duì)象添加屬性和方法,然后返回

優(yōu)點(diǎn)

  1. 再不用創(chuàng)建構(gòu)造函數(shù)的情況下,實(shí)現(xiàn)了原型鏈繼承,代碼量減少一部分
  2. 可以給備份的對(duì)象添加一些屬性

缺點(diǎn)

類似構(gòu)造函數(shù)一樣,創(chuàng)建寄生的方法需要在clone對(duì)象上面添加一些想要的屬性,這些屬性是放在clone上面的一些私有的屬性

寄生組合繼承

咱們看了上面的組合繼承看上去已經(jīng)很完美了,但是也有缺點(diǎn)(父類被實(shí)例化兩次、子類實(shí)例和子類的構(gòu)造函數(shù)都有相同的屬性),寄生組合就是來(lái)解決這些問(wèn)題的

代碼實(shí)現(xiàn):

function inheritPrototype({SubType,SuperType}){
   const prototype = Object(SuperType.prototype);
   prototype.constrcutor=SubType;
   SubType.prototype=prototype;
}
function SuperType(name){
  this.name=name;
  this.friends=['a','b']
}
SuperType.prototype.getName=function(){
  return this.name;
}
function SubType(name,age){
  this.age=age;
  SuperType.call(this,name)
}
inheritPrototype({SubType,SuperType});
SubType.prototype.getAge=function(){
  return this.age
}
var SubTypeShiny = new SubType('Shiny',23);
SubTypeShiny .friends.push('c')
var SubTypeRed = new SubType('Red',21);
SubTypeRed .friends.push('d')
console.log(SubTypeShiny.getName())//Shiny
console.log(SubTypeShiny.getAge())//22
console.log(SubTypeShiny.friends)//['a','b','c']
console.log( SubTypeRed.getName())//Red
console.log( SubTypeRed.getAge())//21
console.log( SubTypeRed.friends)//['a','b','d']

基本原理

子類構(gòu)造函數(shù)內(nèi)通過(guò)call、apply方法進(jìn)行修改父類構(gòu)造函數(shù)的this和執(zhí)行父類構(gòu)造函數(shù),使的子類的實(shí)例擁有父類構(gòu)造函數(shù)的一些屬性,
結(jié)合子類的原型修改成父類構(gòu)造函數(shù)的原型,并把父類的原型的constructor指向子類構(gòu)造函數(shù)

使用場(chǎng)景

在考不使用構(gòu)造函數(shù)的情況下實(shí)現(xiàn)繼承,前面示

范繼承模式時(shí)使用的 object()函數(shù)不是必需的;任何能夠返回新對(duì)象的函數(shù)都適用于此模式

語(yǔ)言實(shí)現(xiàn)

極度類似組合寄生方式,只是修改了子類原型鏈繼承的方式,組合寄生是繼承父類的實(shí)例,寄生組合寄生則是通過(guò)一子類的原型繼承父類的原型,并把該原型的constructor指向子類構(gòu)造函數(shù)

優(yōu)點(diǎn)

  1. 在少一次實(shí)例化父類的情況下,實(shí)現(xiàn)了原型鏈繼承和借用構(gòu)造函數(shù)
  2. 減少了原型鏈查找的次數(shù)(子類直接繼承超類的prototype,而不是父類的實(shí)例)

缺點(diǎn)

暫無(wú)

下面是組合繼承和寄生組合繼承的原型圖對(duì)比

以上所述是小編給大家介紹的javascript繼承詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Jquery代碼實(shí)現(xiàn)圖片輪播效果(一)

    Jquery代碼實(shí)現(xiàn)圖片輪播效果(一)

    經(jīng)理交給我一個(gè)網(wǎng)站新聞資訊網(wǎng)頁(yè)開(kāi)發(fā)的活兒,對(duì)于我這樣的java程序員,沒(méi)有接觸過(guò)網(wǎng)頁(yè)設(shè)計(jì)這么高端的東東,該怎么搞呢,去度娘那搜索到不少結(jié)果,而且很大部分都是用jquery做的,于是根據(jù)自己的一些的理解,提供了這篇jquery輪播效果的講解,有需要的朋友可以來(lái)參考下
    2015-08-08
  • JavaScript利用canvas實(shí)現(xiàn)鼠標(biāo)跟隨特效

    JavaScript利用canvas實(shí)現(xiàn)鼠標(biāo)跟隨特效

    canvas是一個(gè)很神奇的玩意兒,比如畫(huà)表格、畫(huà)海報(bào)圖都要用canvas去做。本文就來(lái)利用canvas制作個(gè)簡(jiǎn)單的鼠標(biāo)跟隨特效,快跟隨小編一起學(xué)習(xí)一下吧
    2022-10-10
  • JavaScript中的異常捕捉介紹

    JavaScript中的異常捕捉介紹

    這篇文章主要介紹了JavaScript中的異常捕捉介紹,本文講解了throw語(yǔ)句拋出異常,try/catch/finally語(yǔ)句捕捉異常,需要的朋友可以參考下
    2014-12-12
  • 微信小程序使用uni-app和springboot實(shí)現(xiàn)一鍵登錄功能(JWT鑒權(quán))

    微信小程序使用uni-app和springboot實(shí)現(xiàn)一鍵登錄功能(JWT鑒權(quán))

    微信一鍵登錄是指用戶在使用小程序時(shí),可以通過(guò)微信賬號(hào)進(jìn)行快速登錄,而無(wú)需額外的注冊(cè)和密碼設(shè)置,這篇文章主要給大家介紹了關(guān)于微信小程序使用uni-app和springboot實(shí)現(xiàn)一鍵登錄功能的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • 微信小程序?qū)崿F(xiàn)課程選擇器

    微信小程序?qū)崿F(xiàn)課程選擇器

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)課程選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 如何利用Three.js實(shí)現(xiàn)跳一跳小游戲

    如何利用Three.js實(shí)現(xiàn)跳一跳小游戲

    最近在公司寫(xiě)H5的3D游戲,選擇了ThreeJS去做,做的過(guò)程中遇到了很多問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于如何利用Three.js實(shí)現(xiàn)跳一跳小游戲的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • 詳解Bootstrap glyphicons字體圖標(biāo)

    詳解Bootstrap glyphicons字體圖標(biāo)

    本章將講解Bootstrap glyphicons字體圖標(biāo),并通過(guò)一些實(shí)例了解它的使用,字體圖標(biāo)是在 Web 項(xiàng)目中使用的圖標(biāo)字體。字體圖標(biāo)在下載的Bootstrap的fonts文件夾中
    2016-01-01
  • 正則表達(dá)式,替換所有HTML標(biāo)簽的簡(jiǎn)單實(shí)例

    正則表達(dá)式,替換所有HTML標(biāo)簽的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇正則表達(dá)式,替換所有HTML標(biāo)簽的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • prototype.js簡(jiǎn)單實(shí)現(xiàn)ajax功能示例

    prototype.js簡(jiǎn)單實(shí)現(xiàn)ajax功能示例

    這篇文章主要介紹了prototype.js簡(jiǎn)單實(shí)現(xiàn)ajax功能,結(jié)合實(shí)例形式分析了prototype.js前臺(tái)實(shí)現(xiàn)ajax與后臺(tái)struts的相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • bootstrap的工具提示實(shí)例代碼

    bootstrap的工具提示實(shí)例代碼

    Bootstrap 工具提示(Tooltip)插件 當(dāng)您想要描述一個(gè)鏈接的時(shí)候,工具提示(Tooltip)就顯得非常有用。這篇文章通過(guò)實(shí)例代碼給大家介紹bootstrap的工具提示功能,需要的朋友參考下吧
    2017-05-05

最新評(píng)論