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

一篇文章教你JS函數(shù)繼承

 更新時(shí)間:2021年09月07日 15:51:16   作者:北極光之夜。  
這篇文章主要介紹了js繼承方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一. 前言:

Hello,大家最近過(guò)得好嗎,😃。函數(shù)繼承是在JS里比較基礎(chǔ)也是比較重要的一部分,而且也是面試中常常要問(wèn)到的。下面帶你快速了解JS中有哪幾種是經(jīng)常出現(xiàn)且必須掌握的繼承方式。掌握下面的內(nèi)容面試也差不多沒(méi)問(wèn)題啦~

當(dāng)然,這需要一定的原型鏈基礎(chǔ),對(duì)原型鏈不熟悉的可以看我這篇文章👉:速識(shí)js原型鏈。

二.原型鏈繼承:

原型鏈繼承的要點(diǎn)在于父類的實(shí)例作為子類的原型。直接看下面這個(gè)例子:

 // 父函數(shù) Person
  function Person(name, age) {
    // 定義一些屬性
    this.name = name;
    this.age = age;
    this.nature = ["auroras", "wind", "moon"];
  }
 // 定義Person原型上的一個(gè)方法
  Person.prototype.sayLove = function () {
    console.log(this.name + " like " + this.nature[0]);
  };
  // 子函數(shù) Jack
  function Jack() {}
  // 父類的實(shí)例作為子類的原型 (-------------------實(shí)現(xiàn)核心--------------------------)
  Jack.prototype = new Person();

現(xiàn)在我們創(chuàng)建兩個(gè)Jack 的實(shí)例,測(cè)試看是否實(shí)現(xiàn)了繼承Person:

      var jack1 = new Jack();
      var jack2 = new Jack();
      jack2.nature[0] = "sea";
      jack1.sayLove();
      jack2.sayLove();   
      console.log(jack1.nature);
      console.log(jack2.nature);  

看運(yùn)行結(jié)果確實(shí)繼承了,能執(zhí)行sayLove方法。但有甚多缺點(diǎn),創(chuàng)建Jack實(shí)例的時(shí)候傳遞不了參數(shù)name和age,而且不同實(shí)例間nature引用類型屬性相互影響,一個(gè)改變那都改變:

在這里插入圖片描述

三.借用構(gòu)造函數(shù)繼承(對(duì)象偽裝):

核心在于“盜用構(gòu)造函數(shù)”(constructor stealing)。在子類構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù)。因?yàn)楫吘购瘮?shù)就是在特定上下文中執(zhí)行代碼的簡(jiǎn)單對(duì)象,所以可以使用apply()和call()方法以新創(chuàng)建的對(duì)象為上下文執(zhí)行構(gòu)造函數(shù)。它能解決原型鏈繼承中傳參數(shù)和引用類型屬性沖突。還是直接看例子:

 // 父函數(shù) Person
  function Person(name, age) {
    // 定義一些屬性
    this.name = name;
    this.age = age;
    this.nature = ["auroras", "wind", "moon"];
  }
 // 定義Person原型上的一個(gè)方法
  Person.prototype.sayLove = function () {
    console.log(this.name + " like " + this.nature[0]);
  };
  // 子函數(shù) Lucy
  function Lucy(name, age) {
  // 通過(guò)call把this指向Lucy,相當(dāng)于拷貝了一份父函數(shù) Person 里的內(nèi)容(---------實(shí)現(xiàn)核心--------------)
        Person.call(this, name, age);
      }
  //給子函數(shù)原型上也定義一個(gè)方法
   Lucy.prototype.syaName = function () {
        console.log("My name is " + this.name);
      };

現(xiàn)在我們創(chuàng)建兩個(gè)Lucy 的實(shí)例,測(cè)試看是否實(shí)現(xiàn)了繼承Person:

      var lucy1 = new Lucy("lucy1", "20");
      var lucy2 = new Lucy("lucy2", "22");
      lucy2.nature[0] = "sea";
      console.log(lucy1.name);
      console.log(lucy1.nature);
      console.log(lucy2.nature);
      lucy1.syaName();
      lucy2.syaName();
      lucy1.sayLove();

結(jié)果看可以繼承了,能傳參數(shù),引用類型屬性也不互相影響,但是缺點(diǎn)顯而易見,可以看到報(bào)錯(cuò),無(wú)法使用父類的原型上的方法sayLove。

在這里插入圖片描述

四.組合繼承:

組合繼承就是結(jié)合了原型鏈繼承和借用構(gòu)造函數(shù)繼承兩者的核心實(shí)現(xiàn)的一種繼承方法,既能傳遞參數(shù),引用類型屬性也互不影響,同時(shí)子類也能獲取得到父類的方法。這也是目前比較常用的繼承方式。直接看例子:

 // 父函數(shù) Person
  function Person(name, age) {
    // 定義一些屬性
    this.name = name;
    this.age = age;
    this.nature = ["auroras", "wind", "moon"];
  }
 // 定義Person原型上的一個(gè)方法
  Person.prototype.sayLove = function () {
    console.log(this.name + " like " + this.nature[0]);
  };
  // 子函數(shù)Lisa
      function Lisa(name, age) {
// 通過(guò)call把this指向Lisa,相當(dāng)于拷貝了一份父函數(shù) Person 里的內(nèi)容(------實(shí)現(xiàn)核心-----------)      
        Person.call(this, name, age);
      }
// 父類的實(shí)例作為子類的原型 (--------------實(shí)現(xiàn)核心-------------------)      
      Lisa.prototype = new Person();
  //小知識(shí)點(diǎn),這里是讓Lisa的constructor重新指向Lisa,不然因?yàn)長(zhǎng)isa的原型為Person實(shí)例,constructor會(huì)指向Person
      Lisa.prototype.constructor = Lisa;

現(xiàn)在我們創(chuàng)建兩個(gè)Lisa 的實(shí)例,測(cè)試看是否實(shí)現(xiàn)了繼承Person:

      var lisa1 = new Lisa("lisa1", "20");
      var lisa2 = new Lisa("lisa2", "21");
      lisa2.nature[0] = "sea";
      console.log(lisa1.name);
      console.log(lisa1.nature);
      console.log(lisa2.nature);
      lisa1.sayLove();
      lisa2.sayLove();

可以看到基本上實(shí)現(xiàn)了我們繼承的功能。也修補(bǔ)了原型鏈和借用構(gòu)造函數(shù)繼承的缺點(diǎn)。但是呢,它還是有一個(gè)小缺點(diǎn),就是可以看到在代碼注釋實(shí)現(xiàn)核心那,兩次都調(diào)用了Person,那么Lisa原型上和實(shí)例上有了兩份相同的屬性,那就會(huì)多少有一些性能浪費(fèi)。

在這里插入圖片描述

五.寄生組合繼承:

其實(shí)寄生組合繼承和組合繼承差不多的,就是多了一個(gè)解決組合繼承上原型和實(shí)例產(chǎn)生兩份相同屬性的缺點(diǎn)。解決核心是我們既然只是想要子類原型賦值為父類原型,那沒(méi)必要new一個(gè)父類實(shí)例。直接創(chuàng)造一個(gè)新對(duì)象,它值為父類的原型,再將它賦值給子類原型就行了。

其中用到Object.create(proto,[propertiesObject])這個(gè)方法創(chuàng)建一個(gè)新對(duì)象。相當(dāng)于新對(duì)象的__proto__為其參數(shù)proto。當(dāng)然Object.create可能低版本ie沒(méi)有,所以下面也自定義封裝了Object.create方法,當(dāng)然只是簡(jiǎn)單封裝。直接看例子:

 // 父函數(shù) Person
  function Person(name, age) {
    // 定義一些屬性
    this.name = name;
    this.age = age;
    this.nature = ["auroras", "wind", "moon"];
  }
 // 定義Person原型上的一個(gè)方法
  Person.prototype.sayLove = function () {
    console.log(this.name + " like " + this.nature[0]);
  };
  // 子函數(shù) Andy
 function Andy(name, age) {
        Person.call(this, name, age);
      }
// 如果沒(méi)有 Object.create()方法,簡(jiǎn)單封裝下
      if (!Object.create) {
        Object.create = function (proto) {
          function Temp() {}
          Temp.prototype = proto;
          return new Temp();
        };
      }
// 調(diào)用Object.create方法,新建一對(duì)像,其__proto__為Person.prototype,并賦值給 Andy.prototype (-------實(shí)現(xiàn)核心----------)
      Andy.prototype = Object.create(Person.prototype);
  //修改constructor指向
      Andy.prototype.constructor = Andy;

現(xiàn)在我們創(chuàng)建兩個(gè)Andy的實(shí)例,測(cè)試看是否實(shí)現(xiàn)了繼承Person:

      console.log(Andy.prototype.__proto__ === Person.prototype);
      var andy1 = new Andy("andy1", "20");
      var andy2 = new Andy("andy2", "21");
      andy2.nature[0] = "sea";
      console.log(andy1.name);
      console.log(andy1.nature);
      console.log(andy2.nature);
      andy1.sayLove();
      andy2.sayLove();

完美運(yùn)行:

在這里插入圖片描述

六.class繼承:

ES6出了class語(yǔ)法糖之后,就可以通過(guò)class定義類并實(shí)現(xiàn)類的繼承。直接看例子:

//定義一個(gè)父類 Animal
  class Animal {
   //這里constructor指向類本身,跟es5行為一樣的
    constructor(name) {
      this.name = name;
    }
    likeEat() {
      console.log(this.name + " like eat " + this.food);
    }
  }
//定義一個(gè)子類 Dog ,通過(guò) extends 繼承父類Animal
  class Dog extends Animal {   
    constructor(name, food) {
      //通過(guò)super(屬性名)繼承父類屬性
     super(name);
     this.food = food;
    }
    likeEat() {
     //通過(guò)super.+父類方法 實(shí)現(xiàn)繼承父類方法
      super.likeEat();
    }
  }

new一個(gè)Dog實(shí)例,測(cè)試看看,Dog是否繼承了Animal:

  var jinmao = new Dog("jinmao", "bone");
  console.log(jinmao.name);
  jinmao.likeEat();

可以看到完美實(shí)現(xiàn)了:

在這里插入圖片描述

七.總結(jié):

方法 優(yōu)點(diǎn) 缺點(diǎn)
原型鏈繼承 能繼承父原型上屬性方法等等… 無(wú)法傳參、引用類型屬性沖突等等…
借用構(gòu)造函數(shù)繼承 可以傳參,引用類型屬性不沖突等等… 無(wú)法繼承父原型上方法等等…
組合繼承 有上面兩種的優(yōu)點(diǎn),并解決其缺點(diǎn) 調(diào)用兩次父實(shí)例產(chǎn)生兩份相同屬性等等…
寄生組合繼承 有上面三種優(yōu)點(diǎn),并解決其缺點(diǎn) 可能不太直觀等等…
class繼承 es6新語(yǔ)法,簡(jiǎn)潔直觀等等… 低版本ie不支持es6等等…

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • 淺談javascript alert和confirm的美化

    淺談javascript alert和confirm的美化

    window對(duì)象的alert和confirm標(biāo)準(zhǔn)方法在不同瀏覽器的顯示效果不太相同,有個(gè)相同點(diǎn)是都不是很美觀。本文對(duì)此解決方法進(jìn)行介紹:使用js和css分別仿照它們,提供另一套函數(shù),使在不同瀏覽器的有著相同的體驗(yàn)效果。下面就跟小編一起來(lái)看下吧
    2016-12-12
  • js中document.getElementById(id)的具體用法

    js中document.getElementById(id)的具體用法

    本文主要介紹了js中document.getElementById(id)的具體用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 微信小程序?qū)崿F(xiàn)日歷簽到

    微信小程序?qū)崿F(xiàn)日歷簽到

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)日歷簽到功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • 微信小程序?qū)崿F(xiàn)單選選項(xiàng)卡切換效果

    微信小程序?qū)崿F(xiàn)單選選項(xiàng)卡切換效果

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)單選選項(xiàng)卡切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • JS實(shí)現(xiàn)左側(cè)菜單工具欄

    JS實(shí)現(xiàn)左側(cè)菜單工具欄

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)左側(cè)菜單工具欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Javascript實(shí)現(xiàn)視頻輪播在pc端與移動(dòng)端均可

    Javascript實(shí)現(xiàn)視頻輪播在pc端與移動(dòng)端均可

    用Javascript實(shí)現(xiàn)視頻輪播,畢竟是客戶的需求嗎?所以盡量實(shí)現(xiàn)下,下面有個(gè)實(shí)現(xiàn)視頻輪播的示例,pc端與移動(dòng)端均可以實(shí)現(xiàn),感興趣的朋友可以了解下
    2013-09-09
  • JavaScript?自定義對(duì)象方法匯總

    JavaScript?自定義對(duì)象方法匯總

    這篇文章主要介紹了JavaScript?自定義對(duì)象,主要介紹一些方法object創(chuàng)建對(duì)象、使用構(gòu)造函數(shù)創(chuàng)建對(duì)象、字面量創(chuàng)建對(duì)象、等展開話題,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2021-12-12
  • JS實(shí)現(xiàn)給對(duì)象動(dòng)態(tài)添加屬性的方法

    JS實(shí)現(xiàn)給對(duì)象動(dòng)態(tài)添加屬性的方法

    這篇文章主要介紹了JS實(shí)現(xiàn)給對(duì)象動(dòng)態(tài)添加屬性的方法,涉及JS屬性的遍歷、動(dòng)態(tài)賦值及eval方法的簡(jiǎn)單使用技巧,需要的朋友可以參考下
    2017-01-01
  • js新聞滾動(dòng) js如何實(shí)現(xiàn)新聞滾動(dòng)效果

    js新聞滾動(dòng) js如何實(shí)現(xiàn)新聞滾動(dòng)效果

    JS實(shí)現(xiàn)新聞滾動(dòng)效果:滾動(dòng)頻率由setTimeout(F,#%18?10:3000)這個(gè)3000來(lái)控制,感興趣的朋友可以了解下哦
    2013-01-01
  • NestJS使用class-validator進(jìn)行數(shù)據(jù)驗(yàn)證

    NestJS使用class-validator進(jìn)行數(shù)據(jù)驗(yàn)證

    本文將通過(guò)詳細(xì)的步驟和實(shí)戰(zhàn)技巧,帶大家掌握如何在NestJS中使用class-validator進(jìn)行數(shù)據(jù)驗(yàn)證,以及11條實(shí)戰(zhàn)中常用的驗(yàn)證技巧,感興趣的可以了解下
    2024-11-11

最新評(píng)論

罗山县| 儋州市| 黎平县| 龙井市| 乐都县| 申扎县| 吉水县| 荔波县| 宁蒗| 临邑县| 宣威市| 衢州市| 六枝特区| 井冈山市| 得荣县| 平武县| 深泽县| 长治县| 鞍山市| 教育| 宁强县| 海兴县| 开远市| 蓬溪县| 新巴尔虎左旗| 秦皇岛市| 顺义区| 祁东县| 浑源县| 庆云县| 四子王旗| 寻甸| 清丰县| 威远县| 阳原县| 平和县| 碌曲县| 曲周县| 虎林市| 五华县| 遂溪县|