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

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

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

先貼一張圖:

1、原型鏈繼承

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

缺點(diǎn):

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

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

缺點(diǎn):

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

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

例子:

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"] (不會被修改)

3、組合繼承

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

缺點(diǎn):組合繼承是js最常用的繼承模式,組合繼承最大的問題就是無論在什么情況下,都會調(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"]

解決的問題:

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

存在的問題:

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

4、寄生組合繼承

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

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

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

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

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

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

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

但不會在 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); // 繼承方法,但不會執(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可以通過extends關(guān)鍵字實(shí)現(xiàn)繼承,還可以通過static關(guān)鍵字定義類的靜態(tài)方法,這比 ES5 的通過修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多。

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

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

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

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

  • super(name) 等價(jià)于 Parent.call(this, name)(繼承實(shí)例屬性)。
  • extends 通過 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ù)繼承 的折中方案,直接基于對象創(chuàng)建新對象。

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

例子:

// 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,{
        //定義該原型對象里每個(gè)變量的屬性
        name:{
          //該變量的值
          value:'小黃',
          //該變量是否可寫
          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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

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

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

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

    這篇文章主要介紹的是通過js簡單實(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)下拉圖片自動加載效果,和百度圖片效果類似,需要的朋友可以參考下
    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 樣式的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • JS中filter( )數(shù)組過濾器的使用

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

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

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

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

最新評論

杂多县| 嫩江县| 峨山| 资中县| 东安县| 衡阳县| 卓尼县| 水城县| 白沙| 耒阳市| 武隆县| 徐汇区| 东光县| 伊吾县| 陵川县| 泾阳县| 阿瓦提县| 贵溪市| 宿松县| 视频| 田林县| 金塔县| 北川| 新干县| 巨野县| 仪征市| 永福县| 海阳市| 方城县| 柳河县| 读书| 岳阳市| 阿巴嘎旗| 图木舒克市| 惠水县| 濮阳县| 精河县| 农安县| 庆元县| 铜山县| 江陵县|