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

JavaScript實現繼承的7種方式總結

 更新時間:2023年04月03日 10:48:00   作者:布魯斯要藍調  
用官方點的話講繼承是面向對象三大特征之一,可以使得子類具有父類的屬性和方法,同時還可以在子類中重新定義以及追加屬性和方法。本文整理了JavaScript實現繼承的7種方式,需要的可以了解一下

什么是繼承

用官方點的話講繼承是面向對象三大特征之一,可以使得子類具有父類的屬性和方法,同時還可以在子類中重新定義以及追加屬性和方法。通俗的來說繼承就是子類可以從父類那里復用一些屬性和方法,從而達到復用代碼的一個效果。

實現繼承的6種方式

  • 原型鏈繼承
  • 構造函數繼承
  • 組合繼承(偽經典繼承)
  • 原型式繼承
  • 寄生式繼承
  • 寄生組合式繼承
  • class 類繼承

1. 原型鏈繼承

function Person() {
    this.name = 'bruce'
    this.age = 18
    this.gender = '男'
    this.like = {
        sport: 'running',
        book: 'JavaScript'
    }
    this.getName = function() {
        console.log(this.name);
    }
}

function Student() {
    this.school = '新華小學'
}

let s = new Student()
console.log(s.name);   // 未繼承前 undefined

Student.prototype = new Person()  // 繼承之后
let s1 = new Student()
s1.getName()  // bruce
console.log(s1.like.book);  // JavaScript
s1.like.book = 'Java'   // 修改引用類型的值
s1.name = 'jack'  // 修改非引用類型的值
console.log(s1.like.book);  // Java
s1.getName()  // jack
console.log('----------');
let s2 = new Student()
s2.getName()  // bruce
console.log(s2.like.book);  // Java

所謂的原型鏈繼承,在我的理解就是子類通過原型鏈來繼承到父類的屬性,在上面的代碼中我們也可以看到在子類實例s沒有繼承到父類的屬性時,子類去訪問父類才有的屬性值為:undefined。

在將父類實例對象掛載到子類Student構造函數的原型上面后,那么此時子類的原型上面就有了父類的全部屬性。因為Person的實例對象被顯示的掛載到了Student的原型上面。所以子類在繼承之后,所有實例化的子類都擁有了跟父類一樣的屬性,于是這樣子類就通過原型鏈實現了繼承。

優(yōu)點: 子類可以繼承到父類的方法。

缺點:

  • 會在子類實例上共享父類所有的引用類型數據,也就是子類的原型被父類屬性覆蓋。
  • 子類實例不能給父類構造函數傳參。
function Person(t) {
    this.property = t
}

function Student(t) {
    this.typeproperty = t
}
Student.prototype = new Person()
let s=new Student('a')
console.log(s.property)  // undefined
console.log(s.typeproperty)  // a

這樣子類實例傳的參數就不能給到父類構造函數里面了。

2. 構造函數繼承

function Person(name,age) {
    this.name = name
    this.age = age
    this.like = {
        sport: 'running',
        book: 'JavaScript'
    }
    this.getName = function () {
        console.log(this.name);
    }
}
Person.prototype.sayHello = function () {
    console.log('你好');
}

function Student(name, age,) {
    Person.call(this, name, age)  // 借用構造函數
}

let s1 = new Student('bruce',18)
s1.getName()   // bruce
s1.name='jack'
s1.getName()  // jack
s1.like.sport='swimming'
console.log(s1.like.sport);  // swimming
console.log('------');
let s2=new Student('lucy',19)
s2.getName()  // lucy
console.log(s2.like.sport);  // running 

構造函數繼承就是使用強制改變 this 指向,借用一個構造函數繼承。相較于原型鏈繼承,構造函數繼承不會共享父類上的引用類型數據,不會互相影響。

缺點:1.不能訪問到父類原型屬性上面的方法和參數,即 Person.prototype 上的都不能訪問到。

Person.prototype.sayHello = function () {  // 在 Person 的原型上面加一個方法
    console.log('你好');
}

let s1 = new Student('bruce',18)
s1.sayHello()  // s1.sayHello is not a function

3. 組合繼承(偽經典繼承)

相較于原型鏈繼承,構造函數繼承好像已經非常完美了,但是它還是存在著一個最大的缺點就是:不能繼承到父類的原型上面的屬性。但是原型鏈繼承就好像沒有這個問題,如果將這兩個繼承方式組合起來搭配使用是不是就能解決掉所有問題,于是這就有了組合繼承。

function Person(name, age) {
    this.name = name
    this.age = age
    this.like = {
        sport: 'running',
        book: 'JavaScript'
    }
    this.getName = function () {
        console.log(this.name);
    }
}
Person.prototype.sayHello = function () {
    console.log('你好');
}

function Student(name, age) {
    Person.call(this, name, age)  // 構造函數繼承
}
Student.prototype = new Person()  // 原型鏈繼承

let s1 = new Student('bruce', 18)
s1.sayHello() // 你好
console.log(s1);

上面先在子類內使用構造函數繼承將父類的顯示屬性掛載到子類上面,此時仍然存在著構造函數繼承中子類不能訪問到父類原型上面屬性的缺點。

所以下面配合原型鏈繼承將父類實例掛載到子類的原型上,此時子類就可以訪問父類的原型上的屬性,同時構造函數繼承將子類的原型被父類屬性覆蓋的問題解決。

組合繼承將前面兩種繼承的缺點都補全了,但是它也有缺點:

不足:重復調用兩次父類函數。

4. 原型式繼承

function object(o){  // 參數為父類  
    function F(){}  
    F.prototype=o  
    return new F()  
}  
  
const person={  
    sex:'man',  
    age:20  
}  
  
let realPerson=object(person)  
console.log(realPerson.sex);// man  

通過在一個構造函數的原型上掛載父類,此時再將這個掛載了父類的構造函數實例返回出來,那么這個實例的隱式原型就為這個父類,所以此時子類實例對象可以訪問到父類上的屬性,這就是原型式繼承。這個看起來跟理解起來是不是跟原型鏈繼承很像,也挺好理解的。

缺點: 如果父類屬性有引用類型,那么這個引用類型也會被共享出來。

 function object(o){  
    function F(){}  
    F.prototype=o  
    return new F()  
}  
  
const person={  
    sex:'man',  
    age:20,  
    like:{  
        sports:'running'  
    }  
}  
  
let r1=object(person)  
console.log(r1.like);// { sports: 'running' }  
let r2=object(person)  
r2.like.sports='singing'  
console.log(r1.like); // { sports: 'singing' }  

實例化兩個不同的對象,更改 r2 的sports 屬性,結果 r1 的 sports 屬性也被修改。

5. 寄生式繼承

這種繼承方式跟原型式繼承有著異曲同工之妙,只不過可以增強這個父類。其存在的缺點也與原型式繼承一樣。

 function createPerson(original) {  
    var clone = Object.create(original)  
    clone.say = function() {     // 增強這個對象  
        console.log('hello');  
    }  
    return clone  
}  

6.寄生組合式繼承

這個是一個比較完美的繼承方式,使用組合繼承與寄生繼承。

function Person(name, age) {
    this.name = name
    this.age = age
    this.like = {
        sport: 'running',
        book: 'JavaScript'
    }
    this.getName = function () {
        console.log(this.name);
    }
}
Person.prototype.sayHello = function () {
    console.log('你好');
}

function Student(name, age) {
    Person.call(this, name, age)  // 借用構造函數
}
const Fn=function(){}
Fn.prototype=Person.prototype

Student.prototype = new Fn()



let s1 = new Student('bruce', 18)
s1.sayHello() // 你好
console.log(s1);

這種繼承方式結合了組合繼承,借助一個空的構造函數,將父類的原型掛載到這個空的構造函數上面,然后將其附在子類的原型上面,這樣就解決了組合式繼承的缺點。

7.class 類繼承

Class 可以通過extends關鍵字實現繼承,讓子類繼承父類的屬性和方法。

class Person{
    constructor(name){
        this.name=name
    }
}

class Student extends Person{
    constructor(name,age){
        super(name)
        this.age=age
    }
}

let s=new Student('bruce',20)
console.log(s);  //Student { name: 'bruce', age: 20 }

以上就是JavaScript實現繼承的7種方式總結的詳細內容,更多關于JavaScript繼承的資料請關注腳本之家其它相關文章!

相關文章

  • 提高網站性能之 如何對待JavaScript

    提高網站性能之 如何對待JavaScript

    在一個頁面中,每一個外部JavaScript 及CSS文件都會導致一個額外的HTTP請求。所以,如何合理的合并JavaScript 文件及CSS文件也是前端工程師應該考慮的。
    2009-10-10
  • js中的事件捕捉模型與冒泡模型實例分析

    js中的事件捕捉模型與冒泡模型實例分析

    這篇文章主要介紹了js中的事件捕捉模型與冒泡模型,實例分析了js事件的執(zhí)行順序與冒泡模型的原理,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • Layui實現主窗口和Iframe層參數傳遞

    Layui實現主窗口和Iframe層參數傳遞

    今天小編就為大家分享一篇Layui實現主窗口和Iframe層參數傳遞,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 關于頁面被攔截的問題

    關于頁面被攔截的問題

    先來看一下幾個常用瀏覽器的攔截設置
    2010-02-02
  • JS庫 Highlightjs 添加代碼行號的實現代碼

    JS庫 Highlightjs 添加代碼行號的實現代碼

    Highlightjs是一款優(yōu)秀的代碼高亮Js組件,可以很方便地對各種語言編寫的代碼添加語法高亮樣式。本文重點給大家介紹Highlightjs 添加代碼行號的實現代碼,需要的朋友參考下吧
    2017-09-09
  • JS將網址url轉化為JSON格式的方法

    JS將網址url轉化為JSON格式的方法

    這篇文章主要介紹了JS將網址url轉化為JSON格式的方法,需要的朋友可以參考下
    2018-07-07
  • 如何使用proxy實現一個簡單完整的MVVM庫的示例代碼

    如何使用proxy實現一個簡單完整的MVVM庫的示例代碼

    這篇文章主要介紹了如何使用proxy實現一個簡單完整的MVVM庫的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • 用javascript獲取textarea中的光標位置

    用javascript獲取textarea中的光標位置

    Javascript一向以他的靈活隨意而著稱,這也使得它的功能可以非常的強大,而由于沒有比較好的調試工具,又使得它使用起來困難重重,尤其使對于一些初學者,更是感覺到無從下手。今天探討的問題是用javascript獲取textarea中光標的位置。
    2008-05-05
  • echart簡介_動力節(jié)點Java學院整理

    echart簡介_動力節(jié)點Java學院整理

    這篇文章主要介紹了echart簡介,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Layui實現數據表格默認全部顯示(不要分頁)

    Layui實現數據表格默認全部顯示(不要分頁)

    今天小編就為大家分享一篇Layui實現數據表格默認全部顯示(不要分頁),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10

最新評論

白银市| 南乐县| 隆安县| 桂阳县| 隆子县| 高安市| 伊春市| 宜宾县| 清涧县| 余干县| 长丰县| 宁都县| 石首市| 东光县| 额尔古纳市| 且末县| 德阳市| 西乌| 阿拉尔市| 鲁甸县| 南城县| 军事| 上饶市| 彭州市| 漳浦县| 武川县| 商都县| 化州市| 开封县| 田林县| 招远市| 巢湖市| 宜兴市| 勐海县| 岐山县| 伊宁县| 成安县| 民权县| 临高县| 新兴县| 三明市|