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

JavaScript實(shí)現(xiàn)類繼承的方法最全講解

 更新時(shí)間:2025年09月14日 11:30:55   作者:鷓鴣yy  
JavaScript 類繼承通過(guò)extends和super關(guān)鍵字提供了一種直觀的面向?qū)ο缶幊谭绞?基于原型鏈實(shí)現(xiàn),這篇文章主要介紹了JavaScript實(shí)現(xiàn)類繼承的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

先貼一張圖:

1、原型鏈繼承

原型鏈繼承的核心思想是讓子類的 prototype 指向父類的實(shí)例,這樣子類就能訪問(wèn)父類的方法和屬性。

缺點(diǎn):

  1. 子類實(shí)例共享父類的引用屬性:修改 child1.colors 之后,child2.colors 也會(huì)受到影響,因?yàn)?colors 是父類實(shí)例的屬性,所有子類實(shí)例都共享同一個(gè)對(duì)象。
  2. 無(wú)法向父類構(gòu)造函數(shù)傳參:創(chuàng)建子類實(shí)例時(shí),無(wú)法向 Parent 傳遞參數(shù)。

例子:

function Parent() {
  this.name = "Parent";
  this.colors = ["red", "blue", "green"];
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child() {}

Child.prototype = new Parent(); // 關(guān)鍵點(diǎn):讓子類的 prototype 指向父類實(shí)例

const child1 = new Child();
console.log(child1.getName()); // Parent
console.log(child1.colors); // ["red", "blue", "green"]

child1.colors.push("yellow");

const child2 = new Child();
console.log(child2.colors); // ["red", "blue", "green", "yellow"] (被修改了)

2、構(gòu)造函數(shù)

通過(guò)在子類的構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù),并使用 call()apply() 綁定 this,從而避免原型鏈繼承的問(wèn)題。

缺點(diǎn):

  1. 子類無(wú)法繼承父類在原型鏈上的屬性和方法。
  2. 每個(gè)實(shí)例都拷貝一份,占用內(nèi)存大,尤其是方法過(guò)多的時(shí)候。(函數(shù)復(fù)用又無(wú)從談起了,本來(lái)我們用 prototype 就是解決復(fù)用問(wèn)題的)

優(yōu)點(diǎn):解決了通過(guò)原型鏈繼承子類對(duì)于父類引用類型屬性的修改,導(dǎo)致其他子類實(shí)列共享了修改的問(wèn)題

例子:

function Parent(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}

function Child(name) {
  Parent.call(this, name); // 關(guān)鍵點(diǎn):在子類構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù)
}

const child1 = new Child("Child1");
const child2 = new Child("Child2");

child1.colors.push("yellow");

console.log(child1.colors); // ["red", "blue", "green", "yellow"]
console.log(child2.colors); // ["red", "blue", "green"] (不會(huì)被修改)

3、組合繼承

組合繼承(原型鏈繼承+借用構(gòu)造函數(shù)繼承)由于這兩種繼承方式都存在各自的優(yōu)缺點(diǎn),從而將他們優(yōu)點(diǎn)結(jié)合起來(lái),通過(guò)原型繼承父類原型上的屬性和方法,通過(guò)構(gòu)造函數(shù)的方法繼承父類的屬性

缺點(diǎn):組合繼承是js最常用的繼承模式,組合繼承最大的問(wèn)題就是無(wú)論在什么情況下,都會(huì)調(diào)用兩次構(gòu)造函數(shù):一次是在創(chuàng)建子類型原型時(shí),另一次是在子類構(gòu)造函數(shù)內(nèi)部。

優(yōu)點(diǎn):就是可以把方法定義在原型上復(fù)用,每個(gè)實(shí)例又有自己的屬性。組合繼承彌補(bǔ)了原型鏈和盜用構(gòu)造函數(shù)的不足,是js中使用最多的繼承模式。

例子:

function Parent(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child(name, age) {
  Parent.call(this, name); // 調(diào)用父類構(gòu)造函數(shù),繼承實(shí)例屬性
  this.age = age;
}

Child.prototype = new Parent(); // 繼承父類方法
Child.prototype.constructor = Child; // 修正 constructor 指向

const child1 = new Child("Child1", 18);
console.log(child1.getName()); // Child1
console.log(child1.colors); // ["red", "blue", "green"]

解決的問(wèn)題:

  1. 避免了引用屬性共享問(wèn)題
  2. 支持傳參
  3. 方法可以復(fù)用

存在的問(wèn)題:

  • 父類構(gòu)造函數(shù)被調(diào)用了兩次

4、寄生組合繼承

組合繼承存在這一定的效率問(wèn)題,它的父類構(gòu)造函數(shù)始終會(huì)被調(diào)用倆次,一次在創(chuàng)建字類原型時(shí)調(diào)用,另一次在子類構(gòu)造函數(shù)中調(diào)用。本質(zhì)上子類只需要在執(zhí)行時(shí)重寫(xiě)自己的原型就行了。寄生式組合繼承可以算是引用類型繼承的最佳模式。

寄生組合繼承優(yōu)化了組合繼承中的 new Parent(),避免了父類構(gòu)造函數(shù)的重復(fù)調(diào)用。

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

  1. 避免引用屬性共享問(wèn)題
  2. 支持傳參
  3. 方法可以復(fù)用
  4. 避免了 new Parent() 造成的二次調(diào)用

其中拓展一下,Object.create(Parent.prototype) 的原理

Object.create() 會(huì)創(chuàng)建一個(gè)新對(duì)象,并將其 __proto__ 指向參數(shù)對(duì)象:

Child 的實(shí)例能通過(guò)原型鏈訪問(wèn) Parent.prototype 的方法(如 getName)。

但不會(huì)在 Child.prototype 上生成多余的父類屬性(如 colors)。

Child.prototype = Object.create(Parent.prototype);
// 相當(dāng)于:
Child.prototype = {};
Child.prototype.__proto__ = Parent.prototype;

例子:

function Parent(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child(name, age) {
  Parent.call(this, name); // 繼承屬性
  this.age = age;
}
// 實(shí)現(xiàn)原型方法繼承。只繼承原型方法,不調(diào)用構(gòu)造函數(shù)
Child.prototype = Object.create(Parent.prototype); // 繼承方法,但不會(huì)執(zhí)行 Parent 構(gòu)造函數(shù)
Child.prototype.constructor = Child; // 修正 constructor 指向

const child1 = new Child("Child1", 18);
console.log(child1.getName()); // Child1
console.log(child1.colors); // ["red", "blue", "green"]

5、ES6中class+extends 的繼承

ES6中引入了class關(guān)鍵字,class可以通過(guò)extends關(guān)鍵字實(shí)現(xiàn)繼承,還可以通過(guò)static關(guān)鍵字定義類的靜態(tài)方法,這比 ES5 的通過(guò)修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多。

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

  1. 語(yǔ)法簡(jiǎn)潔,易讀易寫(xiě)
  2. 繼承邏輯清晰
  3. super()??????? 關(guān)鍵字提供更清晰的繼承機(jī)制

ES5 的繼承,實(shí)質(zhì)是先創(chuàng)造子類的實(shí)例對(duì)象this,然后再將父類的方法添加到this上面(Parent.apply(this))。ES6 的繼承機(jī)制完全不同,實(shí)質(zhì)是先將父類實(shí)例對(duì)象的屬性和方法,加到this上面(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改this。

關(guān)鍵點(diǎn)

  • super(name) 等價(jià)于 Parent.call(this, name)(繼承實(shí)例屬性)。
  • extends 通過(guò) Object.create() 實(shí)現(xiàn)原型方法的繼承。

例子:

class Parent {
  constructor(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
  }

  getName() {
    return this.name;
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name); // 調(diào)用父類構(gòu)造函數(shù),初始化子類的實(shí)例屬性(相當(dāng)于 Parent.call(this))
    this.age = age;
  }
}

const child1 = new Child("Child1", 18);
console.log(child1.getName()); // Child1
console.log(child1.colors); // ["red", "blue", "green"]

6、原型式繼承(額外拓展一個(gè))

原型式繼承原型鏈繼承構(gòu)造函數(shù)繼承 的折中方案,直接基于對(duì)象創(chuàng)建新對(duì)象。

  • 優(yōu)點(diǎn):不需要定義子類構(gòu)造函數(shù),已經(jīng)原型鏈.prototype的指向操作。
  • 缺點(diǎn):父類構(gòu)造函數(shù)的變量值還是會(huì)共享,保持原型鏈繼承的特征。

例子:

// Object.create()底層實(shí)現(xiàn)原理 (ES6的新特性)
      Object.create =  function (o) {
        var F = function () {};
        F.prototype = o;
        return new F();
      };

      let person = {
        name:'薩哈',
        things:[]
      }


      let a = Object.create(person)
      a.name = '小紅'
      a.things.push('筆')
      console.log('a',a)

      let b = Object.create(person,{
        //定義該原型對(duì)象里每個(gè)變量的屬性
        name:{
          //該變量的值
          value:'小黃',
          //該變量是否可寫(xiě)
          writable: false,
          //該變量是否能遍歷
          enumerable:true,
          //是否允許外部操作修改這個(gè)變量的其它屬性值(value屬性除外)
          configurable:true
        }
      })
      b.name = '我要修改'
      console.log('b',b)

總結(jié) 

到此這篇關(guān)于JavaScript實(shí)現(xiàn)類繼承方法的文章就介紹到這了,更多相關(guān)JS實(shí)現(xiàn)類繼承內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Bootstrap入門(mén)書(shū)籍之(四)菜單、按鈕及導(dǎo)航

    Bootstrap入門(mén)書(shū)籍之(四)菜單、按鈕及導(dǎo)航

    這篇文章主要介紹了Bootstrap入門(mén)書(shū)籍之(四)菜單、按鈕及導(dǎo)航的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • 解決OneThink中無(wú)法異步提交kindeditor文本框中修改后的內(nèi)容方法

    解決OneThink中無(wú)法異步提交kindeditor文本框中修改后的內(nèi)容方法

    下面小編就為大家?guī)?lái)一篇解決OneThink中無(wú)法異步提交kindeditor文本框中修改后的內(nèi)容方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • JavaScript簡(jiǎn)單實(shí)現(xiàn)合并兩個(gè)Json對(duì)象的方法示例

    JavaScript簡(jiǎn)單實(shí)現(xiàn)合并兩個(gè)Json對(duì)象的方法示例

    這篇文章主要介紹了JavaScript簡(jiǎn)單實(shí)現(xiàn)合并兩個(gè)Json對(duì)象的方法,結(jié)合實(shí)例形式分析了json對(duì)象的遍歷、添加實(shí)現(xiàn)合并的相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • js簡(jiǎn)單實(shí)現(xiàn)交換Li的值

    js簡(jiǎn)單實(shí)現(xiàn)交換Li的值

    這篇文章主要介紹的是通過(guò)js簡(jiǎn)單實(shí)現(xiàn)交換Li的值,需要的朋友可以參考下
    2014-05-05
  • JavaScript中的DSL元編程介紹

    JavaScript中的DSL元編程介紹

    這篇文章主要介紹了JavaScript中的DSL元編程介紹,本文講解了JavaScript元編程、JavaScript eval、JavaScript new Function()等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • 基于JavaScript實(shí)現(xiàn)瀑布流布局(二)

    基于JavaScript實(shí)現(xiàn)瀑布流布局(二)

    這篇文章主要介紹了原生JavaScript實(shí)現(xiàn)瀑布流布局的相關(guān)資料,實(shí)現(xiàn)鼠標(biāo)下拉圖片自動(dòng)加載效果,和百度圖片效果類似,需要的朋友可以參考下
    2016-01-01
  • jJavaScript中toFixed()和正則表達(dá)式的坑

    jJavaScript中toFixed()和正則表達(dá)式的坑

    這篇文章主要介紹了jJavaScript中toFixed()和正則表達(dá)式的坑,toFixed方法可以把Number四舍五入為指定小數(shù)位數(shù)的數(shù)字,具體詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-04-04
  • webpack處理 css\less\sass 樣式的方法

    webpack處理 css\less\sass 樣式的方法

    本篇文章主要介紹了webpack處理 css\less\sass 樣式的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • JS中filter( )數(shù)組過(guò)濾器的使用

    JS中filter( )數(shù)組過(guò)濾器的使用

    這篇文章主要介紹了filter() 數(shù)組過(guò)濾的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • 前端實(shí)現(xiàn)界面元素拖拽功能的3種方式總結(jié)(親測(cè)有效)

    前端實(shí)現(xiàn)界面元素拖拽功能的3種方式總結(jié)(親測(cè)有效)

    這篇文章主要介紹了前端實(shí)現(xiàn)界面元素拖拽功能的3種方式,三種方法分別是純HTML+CSS+JS、Vue模板和Vue全局指令,每種方法都通過(guò)監(jiān)聽(tīng)鼠標(biāo)事件來(lái)實(shí)現(xiàn)元素的拖動(dòng)功能,并通過(guò)控制閥來(lái)確保只有在指定區(qū)域按下鼠標(biāo)時(shí)才開(kāi)始拖動(dòng),需要的朋友可以參考下
    2025-02-02

最新評(píng)論

滁州市| 聊城市| 南乐县| 盐津县| 韶山市| 三台县| 三原县| 台南市| 禹州市| 长汀县| 义马市| 长乐市| 嘉定区| 日土县| 威远县| 武冈市| 即墨市| 高唐县| 鄂尔多斯市| 奉化市| 苏尼特右旗| 富阳市| 正镶白旗| 论坛| 阿荣旗| 洛川县| 石柱| 探索| 隆回县| 郎溪县| 绿春县| 穆棱市| 敦煌市| 临澧县| 军事| 曲靖市| 莱阳市| 教育| 姜堰市| 石林| 密山市|