欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript的ES5實現(xiàn)繼承的4種常用方法小結(jié)

 更新時間:2024年03月24日 14:25:30   作者:小甘不想干  
繼承是面向?qū)ο筌浖夹g(shù)當(dāng)中的一個概念,這篇文章主要為大家詳細(xì)介紹了JavaScript ES5實現(xiàn)繼承的4種常用方法,感興趣的小伙伴可以了解一下

前言

繼承是面向?qū)ο筌浖夹g(shù)當(dāng)中的一個概念。如果一個類別B“繼承自”另一個類別A,就把這個B稱為“A的子類”,而把A稱為“B的父類”也可以稱“A是B的超類”。

繼承的優(yōu)點是可以使得子類具有父類的屬性和方法,而不需要再次編寫相同的代碼,在子類繼承父類的同時,可以重新定義某些屬性,并重寫某些方法,即覆蓋父類的原有屬性和方法,使其獲得與父類不同的功能。

JavaScript實現(xiàn)面向?qū)ο缶幊痰姆绞脚c傳統(tǒng)的面向?qū)ο笳Z言有所不同,它的面向?qū)ο筇匦灾饕谠秃驮玩湙C制,而不是基于類(盡管ES6引入了class關(guān)鍵字,但只是語法糖而已,底層依舊是基于原型的)。

接下來重點說說ES5的4種常用繼承方法

ES5實現(xiàn)的四種方式

1. 原型鏈繼承

原型鏈繼承其實就是讓子類的原型對象指向父類實例,當(dāng)子類實例找不到對應(yīng)的屬性和方法時,就會往它的原型上去找,從而實現(xiàn)對父類的屬性和方法的繼承

// 父類
function Person() {
  this.name = 'gan'
}

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

// 子類
function Student() { }

Student.prototype = new Person()

// 根據(jù)原型鏈的規(guī)則,順便綁定constructor 不影響繼承
Student.prototype.constructor = Student

const student = new Student()

console.log(student.name) // gan

console.log(student.getName()) // gan

缺點

1.所有的Student實例都指向一個Person實例,這樣的話如果Person有一個引用類型的屬性,有一個student1實例改變了它,那么會影響所有的實例

function Person() {
  this.hobby = ['籃球', '足球']
}

function Student() { }

Student.prototype = new Person()

const student1 = new Student()
const student2 = new Student()

student1.hobby.push('排球')
console.log(student1.hobby) // [ '籃球', '足球', '排球' ]
console.log(student2.hobby) // [ '籃球', '足球', '排球' ]

2.子類實例不能向父類構(gòu)造函數(shù)傳參,也就是沒有super()功能

2. 構(gòu)造函數(shù)繼承

構(gòu)造函數(shù)繼承就是在子類的構(gòu)造函數(shù)中執(zhí)行父類的構(gòu)造函數(shù),為父類構(gòu)造函數(shù)綁定子類的this,讓父類的屬性和方法都掛在子類上,這樣即避免每一個子類實例共享一個原型實例,并且這樣也可以向父類傳參

function Person() {
  this.name = 'gan'
}

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

function Student() {
  Person.apply(this, arguments)
}

const student = new Student()
console.log(student.name) // gan

缺點

不能訪問父類的原型

console.log(student.getName) // undefined

3. 組合式繼承

組合式繼承其實就是結(jié)合了原型鏈繼承和構(gòu)造函數(shù)繼承兩種方式

function Person() {
  this.name = 'gan'
}

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

function Student() {
  Person.apply(this, arguments)
}

Student.prototype = new Person()

Student.prototype.constructor = Student

const student = new Student()
console.log(student.getName()) // gan

缺點

每次創(chuàng)建子類實例時需要創(chuàng)建兩遍父類構(gòu)造函數(shù)(Person.apply和new Person),原型中會存在兩份相同的屬性和方法,雖然不影響繼承,但是不夠優(yōu)雅

4. 寄生式組合繼承

解決了執(zhí)行兩次父類構(gòu)造函數(shù)的問題,將指向父類實例改為指向父類原型

function Person() {
  this.name = 'gan'

}

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

function Student() {
  // 構(gòu)造函數(shù)繼承
  Person.apply(this, arguments)
}

// Student.prototype = new Person()
Student.prototype = Object.create(Person.prototype)

Student.prototype.constructor = Student

const student = new Student()
console.log(student.getName()) // gan

這種方法是目前最優(yōu)的辦法

總結(jié)

  • 最開始說到繼承,我們應(yīng)該先想到的是原型鏈繼承,子類的原型對象指向父類實例,但是它的缺點在于子類實例繼承父類引用類型時出現(xiàn)了問題以及實例不能向父類傳參的問題
  • 接著就是構(gòu)造函數(shù)繼承,在子類的構(gòu)造函數(shù)中執(zhí)行父類的構(gòu)造函數(shù),為父類構(gòu)造函數(shù)綁定子類的this,但它也存在缺點就是不能繼承到父類原型鏈上的屬性和方法
  • 后來就有了組合式繼承,是上面兩者的結(jié)合,問題就是每次都會執(zhí)行兩次父類構(gòu)造函數(shù)
  • 最后就有了寄生式組合繼承

到此這篇關(guān)于JavaScript的ES5實現(xiàn)繼承的4種常用方法小結(jié)的文章就介紹到這了,更多相關(guān)JavaScript ES5繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論