最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript常見繼承模式實例小結(jié)

 更新時間:2019年01月11日 10:52:02   作者:jlu16  
這篇文章主要介紹了JavaScript常見繼承模式,結(jié)合實例形式總結(jié)分析了javascript原型鏈繼承、構(gòu)造函數(shù)繼承、組合繼承、原型式繼承、寄生式繼承等相關(guān)實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下

本文實例總結(jié)了JavaScript常見繼承模式。分享給大家供大家參考,具體如下:

JavaScript中并沒有傳統(tǒng)的面向?qū)ο笳Z言中的類的概念,但是卻實現(xiàn)了特殊的繼承機制。

(閱讀此文您首先需要知道原型的知識)

先來說說第一種繼承方式,原型鏈繼承。

一. 原型鏈繼承

所謂原型鏈繼承,就是讓父類的一個實例作為子類的原型。

即 :

parentInstance = new Parent();
child.prototype = parentInstance;

這樣,在創(chuàng)建子類的實例時,子類實例的__proto__指向父類的實例(即此時子類構(gòu)造函數(shù)的prototype屬性),而父類實例的__proto__又指向父類構(gòu)造函數(shù)的prototype屬性。借用這種方式形成了一條原型鏈。

由于JavaScript中搜索實例中調(diào)用的變量有如下方式:

  1. 在當(dāng)前實例中尋找變量名
  2. 在當(dāng)前實例所指向的原型中尋找

假設(shè)原型鏈中有如下繼承關(guān)系:

grandparent(有方法 grandparent.prototype.sayHello) -> parent -> child

當(dāng)在child的實例child_ming調(diào)用方法 sayHello 時,首先在child_ming中(即只定義在child_ming這一個實例中,而非所有實例中)搜索sayHello,并未找到,然后開始搜索它所指向的原型,即parent的實例。在parent的實例中也沒有此方法,開始搜索parent的原型,即grandparent的實例。在grandparent的實例中依然沒有找到,又搜索grandparent的原型并找到該方法。

可以看出,這樣便實現(xiàn)了繼承。

如同在使用prototype創(chuàng)建對象時遇到的問題,倘若完全使用原型鏈進行繼承,會使得一些需要繼承但不需要在不同實例間進行共享的屬性變得不方便實現(xiàn)。

下面就要說一說借用構(gòu)造函數(shù)實現(xiàn)的繼承。

二. 借用構(gòu)造函數(shù)實現(xiàn)繼承

所謂借用構(gòu)造函數(shù)實現(xiàn)繼承,即在子類的構(gòu)造函數(shù)中把父類的構(gòu)造函數(shù)借來使用,以求在子類中生成父類的屬性。

看如下代碼:

function Parent(color){
  this.color = color;
  this.getColor = function(){ alert(this.color); };
}
function Child(color,size){
  Parent.call(this,color);
  this.size = size;
}

這就是一個簡單的借用構(gòu)造函數(shù)的繼承。

通過使用父類的構(gòu)造函數(shù),可以使得同一構(gòu)造函數(shù)的不同的實例的同一屬性擁有不同的值。解決了原型鏈繼承中的屬性共享的弊端。

然而,如同使用構(gòu)造函數(shù)創(chuàng)建對象時遇到的問題,通過構(gòu)造函數(shù)生成的方法面臨著重復(fù)定義的問題,同一類下的不同實例擁有各自的方法,而一般來講方法是需要實現(xiàn)復(fù)用的,沒有必要讓它們擁有各自的方法。

使用組合繼承可以解決這個問題。

三. 組合繼承(原型鏈與借用構(gòu)造函數(shù))

既然原型鏈可以實現(xiàn)屬性共享,借用構(gòu)造函數(shù)可以實現(xiàn)屬性值的私有,不妨將它們結(jié)合起來,這就形成了組合繼承。

所謂組合繼承,實際上就是用一次原型鏈繼承,用一次借用構(gòu)造函數(shù)繼承。

看如下代碼:

function Parent(color){
  this.color = color;
}
Parent.prototype.getColor = function(){ alert(this.color); };
function Child(color,size){
  Parent.call(this,color); //借用構(gòu)造函數(shù)繼承屬性
  this.size = size;
}
//下面的屬性'green'并沒有影響,這里要使用原型繼承方法
Child.prototype = new Parent('green');
var child_demo = new Child('red',200);

首先思考這樣兩個問題,創(chuàng)建一個child 實例到底生成了幾份color 屬性?在代碼中既定義了'red' 又定義了 ‘green',當(dāng)調(diào)用 child_demo.getColor() 時,到底會alert 哪一個?

首先來看第一個問題。由于子類構(gòu)造函數(shù)中借用了父類的構(gòu)造函數(shù),在創(chuàng)建子類實例時必然會生成一次color 屬性。但是不要忘記,我們在繼承方法時是讓子類構(gòu)造函數(shù)的原型指向一個父類的實例,在創(chuàng)建這個父類實例時還要生成一次color 屬性(即上面'green'處),而這個屬性是完全沒有必要存在的。所以一共生成了兩份color 屬性,一個有用一個沒用。

再來看第二個問題。只要能理解this 的含義就可以知道:

child_demo.getColor() // 'red'
Child.prototype.getColor() //'green'

組合繼承結(jié)合了前兩種繼承方式的優(yōu)點,但它也有自己的缺點。從生成兩份color 屬性可以知道在繼承過程中調(diào)用了兩次Parent 的構(gòu)造函數(shù),這會造成執(zhí)行完成速度的問題,影響了效率。但是瑕不掩瑜,這種繼承方式還是成為了JavaScript中最常用的繼承模式。

四. 原型式繼承

原型式繼承是從已有對象的基礎(chǔ)上繼承,基于已有對象創(chuàng)建新的對象。

看如下代碼:

var obj = {
  color: 'red',
  getColor: function(){ alert(this.color); },
};
//getChild(obj)返回的是一個__proto__指向obj的實例
function getChild(obj){
  function func(){}
  func.prototype = obj;
  return new func();
}
var child_demo = getChild(obj);

這種繼承方式與原型鏈?zhǔn)降睦^承方式有相同點和不同點。

相同點:它們都是通過改變子類構(gòu)造函數(shù)的原型屬性來實現(xiàn)繼承,所繼承的屬性都具有不同實例共享的特點。

不同點:原型鏈繼承中子類構(gòu)造函數(shù)的原型(prototype)是父類的一個實例(我們真正需要繼承的東西可能存在于父類構(gòu)造函數(shù)的原型中,也可能存在于直接指向的父類實例中),而原型式繼承中子類構(gòu)造函數(shù)的原型是一個已有的對象,可以說直接就是父類。

五. 寄生式繼承

寄生式繼承可以說是原型式繼承的變體,它對原型式繼承進行了封裝,使得創(chuàng)建子類實例只依賴于一個函數(shù)。

看如下代碼:

var obj = {
  color: 'red',
  getColor: function(){ alert(this.color); },
};
function getChild(obj){
  function func(){}
  func.prototype = obj;
  return new func();
}
/*-------以上是原型式繼承的代碼----------*/
function betterGetChild(obj,size){
  var temp_obj = getChild(obj);
  temp_obj.size = size;
  temp_obj.getSize = function(){ return this.size; };
  return temp_obj;
}
var demo = betterGetChild(obj,200);

六. 寄生組合式繼承

寄生組合式是組合繼承加上原型式繼承的應(yīng)用。由于組合式繼承中子類構(gòu)造函數(shù)的原型指向父類的一個實例而非父類構(gòu)造函數(shù)的原型,會導(dǎo)致設(shè)置子類構(gòu)造函數(shù)的原型時對父類的構(gòu)造函數(shù)進行一次額外的調(diào)用。所以在寄生式組合繼承中,借用原型式繼承的思想,將父類構(gòu)造函數(shù)的原型當(dāng)作一個已有對象,讓子類構(gòu)造函數(shù)的原型直接指向它。

看如下代碼:

function getChild(obj){
  function func(){}
  func.prototype = obj;
  return new func();  //調(diào)用構(gòu)造函數(shù)
}
/*-------以上是原型式繼承的代碼----------*/
function Parent(color){
  this.color = color;
}
Parent.prototype.getColor = function(){
  alert(this.color);
};
function Child(color,size){
  Parent.call(this,color); //調(diào)用構(gòu)造函數(shù)
  this.size = size;
}
//Child.prototype直接指向一個__proto__指向Parent.prototype的實例
Child.prototype = getChild(Parent.prototype);
Child.prototype.getSize = function(){ alert(this.size); };

其實嚴(yán)格來說,這種方式也調(diào)用了兩次構(gòu)造函數(shù),但是其中一次構(gòu)造函數(shù)的調(diào)用是對一個空函數(shù)的調(diào)用,而不是兩次都調(diào)用父類的構(gòu)造函數(shù)。

在組合繼承中,在子類的原型中其實還保存有父類的沒有定義在原型中的屬性(由于子類構(gòu)造函數(shù)的原型是父類的一個實例),只不過是子類構(gòu)造函數(shù)在借用父類構(gòu)造函數(shù)在當(dāng)前實例中生成了覆蓋原型中那些屬性的屬性。而寄生式組合繼承中,根本不會產(chǎn)生那些冗余數(shù)據(jù)。

人們普遍認(rèn)為寄生時組合繼承是最理想的繼承方式。

更多關(guān)于JavaScript相關(guān)內(nèi)容還可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)

希望本文所述對大家JavaScript程序設(shè)計有所幫助。

相關(guān)文章

  • JavaScript Function函數(shù)類型介紹

    JavaScript Function函數(shù)類型介紹

    在JS中,Function(函數(shù))類型實際上是對象;每個函數(shù)都是Function類型的實例;而且都與其他引用類型一樣具有屬性和方法
    2015-04-04
  • 利用canvas實現(xiàn)的加載動畫效果實例代碼

    利用canvas實現(xiàn)的加載動畫效果實例代碼

    之前看到一個Android的加載效果不錯,一直想自己動手做一個,正好這段時間重溫了一個Canvas,所以就嘗試了一下。下面這篇文章主要給大家介紹了關(guān)于利用canvas實現(xiàn)加載效果的相關(guān)資料,需要的朋友可以參考下。
    2017-07-07
  • echarts中g(shù)rid圖表的位置配置詳解

    echarts中g(shù)rid圖表的位置配置詳解

    ECharts是一個純JavaScript圖表庫,底層依賴于輕量級的Canvas類庫ZRender,下面這篇文章主要給大家介紹了關(guān)于echarts中g(shù)rid圖表的位置配置的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • 微信小程序整合使用富文本編輯器的方法詳解

    微信小程序整合使用富文本編輯器的方法詳解

    這篇文章主要介紹了微信小程序整合使用富文本編輯器的方法,結(jié)合實例形式分析了微信小程序整合與使用富文本插件WxParse相關(guān)步驟與操作技巧,需要的朋友可以參考下
    2019-04-04
  • JavaScript中雙向數(shù)據(jù)綁定詳解

    JavaScript中雙向數(shù)據(jù)綁定詳解

    這篇文章主要為大家詳細(xì)介紹了JavaScript中雙向數(shù)據(jù)綁定,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • IE瀏覽器中圖片onload事件無效的解決方法

    IE瀏覽器中圖片onload事件無效的解決方法

    在做一個項目的時候才發(fā)現(xiàn)的這個bug,其實這是一個很常見的問題,只是之前對圖片的處理太少,沒有碰到過。
    2014-04-04
  • 微信小程序頂部導(dǎo)航欄可滑動并選中放大

    微信小程序頂部導(dǎo)航欄可滑動并選中放大

    這篇文章主要介紹了微信小程序頂部導(dǎo)航欄可滑動并選中放大,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • 低門檻開發(fā)iOS、Android、小程序應(yīng)用的前端框架詳解

    低門檻開發(fā)iOS、Android、小程序應(yīng)用的前端框架詳解

    結(jié)合AVM官網(wǎng)的介紹和我自己的一些實踐經(jīng)驗,我總結(jié)了一系列AVM的特性,我想這些內(nèi)容足以讓你主動去學(xué)習(xí)AVM框架了
    2021-10-10
  • webpack5的entry和output配置小白學(xué)習(xí)

    webpack5的entry和output配置小白學(xué)習(xí)

    這篇文章主要為大家介紹了webpack5的entry和output使用配置小白學(xué)習(xí)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • 詳解webpack介紹&安裝&常用命令

    詳解webpack介紹&安裝&常用命令

    本篇文章主要介紹了詳解webpack介紹&安裝&常用命令,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06

最新評論

达州市| 安多县| 察雅县| 高青县| 红河县| 唐河县| 措勤县| 梁河县| 华蓥市| 靖安县| 昌黎县| 唐海县| 洛扎县| 民县| 奇台县| 射洪县| 禹城市| 雷州市| 双城市| 军事| 丹江口市| 台州市| 五原县| 丽江市| 通化市| 罗平县| 邳州市| 贵州省| 文成县| 同仁县| 逊克县| 额尔古纳市| 兰西县| 灵台县| 军事| 东海县| 北碚区| 阿拉尔市| 马关县| 荃湾区| 滨海县|