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

JavaScript類的繼承全面示例講解

 更新時(shí)間:2022年08月08日 09:20:08   作者:夏安  
在 ES5 中,類的繼承可以有多種方式,然而過(guò)多的選擇有時(shí)反而會(huì)成為障礙,ES6 統(tǒng)了類繼承的寫(xiě)法,避免開(kāi)發(fā)者在不同寫(xiě)法的細(xì)節(jié)之中過(guò)多糾纏,但在介紹新方法之前,還是有必要先回顧下ES5中類的繼承方式

1. ES5 中的繼承

首先假設(shè)我們有一個(gè)父類 Person,并且在類的內(nèi)部和原型鏈上各定義了一個(gè)方法:

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greed = function() {
    console.log('Hello, I am ', this.name);
  }
}
Person.prototype.getInfo = function() {
  return this.name + ',' + this.age;
}

1.1 修改原型鏈

這是最普遍的繼承做法,通過(guò)將子類的 prototype 指向父類的實(shí)例來(lái)實(shí)現(xiàn):

function Student() {
}
Student.prototype = new Person();
Student.prototype.name = '夏安';
Student.prototype.age = 18;
const stud = new Student();
stud.getInfo();

在這種繼承方式中,stud 對(duì)象既是子類的實(shí)例,也是父類的實(shí)例。然而也有缺點(diǎn),在子類的構(gòu)造函數(shù)中無(wú)法通過(guò)傳遞參數(shù)對(duì)父類繼承的屬性值進(jìn)行修改,只能通過(guò)修改 prototype 的方式進(jìn)行修改。

1.2 調(diào)用父類的構(gòu)造函數(shù)

function Student(name, age, sex) {
  Person.call(this);
  this.name = name;
  this.age = age;
  this.sex = sex;
}
const stud = new Student('夏安', 18, 'male');
stud.greed(); // Hello, I am  夏安
stud.getInfo(); // Error

這種方式避免了原型鏈繼承的缺點(diǎn),直接在子類中調(diào)用父類的構(gòu)造函數(shù),在這種情況下,stud 對(duì)象只是子類的實(shí)例,不是父類的實(shí)例,而且只能調(diào)用父類實(shí)例中定義的方法,不能調(diào)用父類原型上定義的方法。

1.3 組合繼承

這種繼承方式是前面兩種繼承方式的結(jié)合體。

function Student(name, age, sex) {
  Person.call(this);
  this.name = name;
  this.age = age;
  this.sex = sex;
}
Student.prototype = new Person();
const stud = new Student('夏安', 18, 'male');
stud.greed();
stud.getInfo();

這種方式結(jié)合上面兩種繼承方式的優(yōu)點(diǎn),也是 Node 源碼中標(biāo)準(zhǔn)的繼承方式。唯一的問(wèn)題是調(diào)用了父類的構(gòu)造函數(shù)兩次,分別是在設(shè)置子類的 prototype 和實(shí)例化子類新對(duì)象時(shí)調(diào)用的,這造成了一定的內(nèi)存浪費(fèi)。

1.4 原型繼承

利用一個(gè)空對(duì)象作為中介,將某個(gè)對(duì)象直接賦值給空對(duì)象構(gòu)造函數(shù)的原型。

function createObject(o) {
  // 創(chuàng)建臨時(shí)類
  function f() {
  }
  // 修改類的原型為o, 于是f的實(shí)例都將繼承o上的方法
  f.prototype = o
  return new f()
}

這不就是Object.create嗎? createObject對(duì)傳入其中的對(duì)象執(zhí)行了一次淺復(fù)制,將構(gòu)造函數(shù)f的原型直接指向傳入的對(duì)象。同樣也沒(méi)有解決修改原型鏈的缺點(diǎn)。

1.5 寄生式繼承

在原型式繼承的基礎(chǔ)上,增強(qiáng)對(duì)象,返回構(gòu)造函數(shù),或者說(shuō)使用原型繼承對(duì)一個(gè)目標(biāo)對(duì)象進(jìn)行淺復(fù)制,增強(qiáng)這個(gè)淺復(fù)制的能力。

function Student() {
  const clone = Object.create(Person);
  clone.name = '夏安';
  return clone;
}

同樣也可以和之前的方法進(jìn)行組合,這里就不再贅述。

2. ES6 中的繼承

在 ES6 中可以直接使用 extends 關(guān)鍵字來(lái)實(shí)現(xiàn)繼承,形式上更加簡(jiǎn)潔。我們前面也提到了,ES6 對(duì) Class 的改進(jìn)就是為了避免開(kāi)發(fā)者過(guò)多地在語(yǔ)法細(xì)節(jié)中糾纏。

我們?cè)O(shè)計(jì)一個(gè) student 類來(lái)繼承之前定義的 person 類。

class Student extends Person {
  constructor(name, age, sex) {
    super(name, age);
    this.sex = sex;
  }
  getInfo() {
    return super.getInfo() + ',' + this.sex;
  }
  print() {
    const info = this.getInfo();
    console.log(info);
  }
}
const student = new Student('夏安', 18, 'male');
student.print(); // 夏安,18,male

在代碼中我們定義了 Student 類,在它的構(gòu)造方法中調(diào)用了 super 方法,該方法調(diào)用了父類的構(gòu)造函數(shù),并將父類中的屬性綁定到子類上。

super 方法可以帶參數(shù),表示哪些父類的屬性會(huì)被繼承,在代碼中,子類使用 super 繼承了 Person 類的 name 以及 age 屬性,同時(shí)又聲明了一個(gè) sex 屬性。

在子類中,super 方法是必須要調(diào)用的,原因在于子類本身沒(méi)有自身的 this 對(duì)象,必須通過(guò) super 方法拿到父類的 this 對(duì)象,可以在 super 函數(shù)調(diào)用前嘗試打印子類的 this,代碼會(huì)出現(xiàn)未定義的錯(cuò)誤。

如果子類沒(méi)有定義 constructor 方法,那么在默認(rèn)的構(gòu)造方法內(nèi)部自動(dòng)調(diào)用 super 方法,并繼承父類的全部屬性。

同時(shí),在子類的構(gòu)造方法中,必須先調(diào)用 super 方法,然后才能調(diào)用 this 關(guān)鍵字聲明其他的屬性(如果存在的話),這同樣是因?yàn)樵?super 沒(méi)有調(diào)用之前,子類還沒(méi)有 this 這一緣故。

class Student extends Person {
  constructor(name, age, sex) {
    console.log(this); // Error
    super(name, age);
    this.sex = sex;
  }
}

除了用在子類的構(gòu)造函數(shù)中,super 還可以用在類方法中來(lái)引用父類的方法。

class Student extends Person {
  constructor(name, age, sex) {
    super(name, age);
    this.sex = sex;
  }
  print() {
    const info = super.getInfo(); // 調(diào)用父類方法
    console.log(info);
  }
}

值得注意的是,super 只能調(diào)用父類方法,而不能調(diào)用父類的屬性,因?yàn)榉椒ㄊ嵌x在原型鏈上的,屬性則是定義在類的內(nèi)部(就像組合繼承那樣,屬性定義在類的內(nèi)部)。

class Student extends Person {
  constructor(name, age, sex) {
    super(name, age);
    this.sex = sex;
  }
  getInfo() {
    return super.name; // undefinded
  }
}

此外,當(dāng)子類的函數(shù)被調(diào)用時(shí),使用的均為子類的 this(修改父類的 this 得來(lái)),即使使用 super 來(lái)調(diào)用父類的方法,使用的仍然是子類的 this。

class Person {
  constructor() {
    this.name = '夏安';
    this.sex = 'male';
  }
  getInfo() {
    return this.name + ',' + this.sex;
  }
}
class Student extends Person {
  constructor() {
    super();
    this.name = '安夏';
    this.sex = 'Female';
  }
  print() {
    return super.getInfo();
  }
}
const student = new Student();
console.log(student.print()); // 安夏,Female
console.log(student.getInfo()); // 安夏,Female

在上面的例子中,super 調(diào)用了父類的方法,輸出的內(nèi)容卻是子類的屬性,說(shuō)明 super 綁定了子類的 this。

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

相關(guān)文章

  • 談?wù)凧S中的!!

    談?wù)凧S中的!!

    !!一般用來(lái)將后面的表達(dá)式強(qiáng)制轉(zhuǎn)換為布爾類型的數(shù)據(jù)(boolean),也就是只能是true或者false。下面看看通過(guò)本文給大家介紹了JS中的!!,需要的朋友參考下吧
    2017-12-12
  • 最新JavaScript判斷是否是360瀏覽器方法

    最新JavaScript判斷是否是360瀏覽器方法

    這篇文章主要給大家介紹了關(guān)于最新JavaScript判斷是否是360瀏覽器方法的相關(guān)資料,我們?cè)谧鲰?xiàng)目的時(shí)候有用到判斷不同瀏覽器的這個(gè)需求,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-07-07
  • Bootstrap整體框架之JavaScript插件架構(gòu)

    Bootstrap整體框架之JavaScript插件架構(gòu)

    這篇文章主要介紹了Bootstrap整體框架之JavaScript插件架構(gòu)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • addEventListener()與removeEventListener()解析

    addEventListener()與removeEventListener()解析

    這篇文章主要為大家詳細(xì)介紹了addEventListener()與removeEventListener(),用于處理指定和刪除事件處理程序操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • JavaScript中的變量聲明早于賦值分析

    JavaScript中的變量聲明早于賦值分析

    JavaScript中的變量聲明早于賦值分析,需要的朋友可以參考下
    2012-03-03
  • JavaScript中的數(shù)組使用方法詳解

    JavaScript中的數(shù)組使用方法詳解

    JavaScript數(shù)組是一種特殊類型的對(duì)象,用于存儲(chǔ)多個(gè)值,數(shù)組中的每個(gè)值都有一個(gè)索引,索引從0開(kāi)始,數(shù)組中的值可以是任何數(shù)據(jù)類型,包括數(shù)字、字符串、布爾值、對(duì)象和函數(shù),
    2024-10-10
  • js實(shí)現(xiàn)跨域的4種實(shí)用方法原理分析

    js實(shí)現(xiàn)跨域的4種實(shí)用方法原理分析

    這篇文章主要分析了js實(shí)現(xiàn)跨域的4種實(shí)用方法原理,主要是使用jsonp跨域,使用window.name來(lái)進(jìn)行跨域,對(duì)這方面感興趣的朋友可以參考一下
    2015-10-10
  • js實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制文本功能

    js實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制文本功能

    這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制文本的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 簡(jiǎn)單的兩種Extjs formpanel加載數(shù)據(jù)的方式

    簡(jiǎn)單的兩種Extjs formpanel加載數(shù)據(jù)的方式

    這篇文章介紹了兩種Extjs formpanel加載數(shù)據(jù)的方式,有需要的朋友可以參考一下
    2013-11-11
  • 原生js實(shí)現(xiàn)2048小游戲

    原生js實(shí)現(xiàn)2048小游戲

    這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)2048小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03

最新評(píng)論

土默特左旗| 香港| 福海县| 湖州市| 白水县| 方正县| 开封市| 巴彦淖尔市| 定日县| 鹤庆县| 承德县| 桂林市| 龙岩市| 清新县| 柏乡县| 资源县| 罗源县| 安义县| 舒城县| 张家川| 彭泽县| 涟水县| 新竹市| 灌南县| 河西区| 灌阳县| 大名县| 庐江县| 田林县| 东乡| 新龙县| 双江| 蕉岭县| 河南省| 水城县| 张家界市| 阿拉善右旗| 镇平县| 南漳县| 田东县| 兴安县|