首頁 web前端 js教程 javascript繼承機制實例詳解_javascript技巧

javascript繼承機制實例詳解_javascript技巧

May 16, 2016 pm 04:31 PM
javascript 機制 繼承

本文實例講述了javascript繼承機制。分享給大家供大家參考。具體分析如下:

初學javascript一般很難理解Javascript語言的繼承機制它沒有"子類"和"父類"的概念,也沒有"類"(class)和"實例"(instance)的區分,全靠一種很奇特的"原型鏈"(prototype chain)模式,來實現繼承。

我花了很多時間,學習這個部分,還做了很多筆記。但是都屬於強行記憶,無法從根本上理解。

一、如何建立一個類別

假設有給叫Person的類別如下:

複製程式碼 程式碼如下:
var Person = function(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.getName = function() {
    return this.name;
}

如上:Person代表地球上所有的人,每個人都有這兩個基本屬性:name和age;現在我們要實現一個學生類,然後我們知道了; 學生也是一個人,及學生也有name和age等屬性;現在的問題是怎麼能把這個關係搭起來?
先來看看純粹物件導向的語言是如何做到的(如:Actionscrpt3)
複製程式碼 程式碼如下:
class Students extend Person {}; //很簡單,一行程式碼;更確切的說是一個單字--extend

二、換成js如何能做到

在講解js的繼承機制實作之前,先了解一下js的原型鏈:

複製程式碼

程式碼如下:

var person = new Person('Poised-flw', 21);

person.getName(); // "Poised-flw"


就上面的getName()方法來說,是如何執行的?首先會在Person這個函數裡面找是否有getName()這個方法,發現沒有;然後就轉到 Person.prototype中尋找,發現有!然後就調用,若沒有呢?繼續按照相同的方法一直沿著prototype尋找下去,直到找到方法或 達到原型鏈的頂端為止! 舉例來說,現在有一個叫做DOG的建構函數,表示狗物件的原型。
複製程式碼


程式碼如下:

  function DOG(name){
    this.name = name;複製程式碼


複製程式碼

程式碼如下:

  var dogA = new DOG('大毛');

  var dogA = new DOG('大毛');
  alert(dogA.name); // 大毛

注意建構函式中的this關鍵字,它就代表了新建立的實例物件。 三、new運算子的缺點 用建構函式產生實例對象,有一個缺點,那就是無法共享屬性和方法。
例如,在DOG物件的建構子中,設定一個實例物件的共有屬性species。



複製程式碼

然後,產生兩個實例物件:



複製程式碼
複製程式碼 程式碼如下:
  var dogA = new DOG('大毛');
  var dogA = new DOG('大毛');
  var dogB = new DOG('二毛'); 這兩個物件的species屬性是獨立的,修改其中一個,不會影響到另一個。 複製程式碼 程式碼如下:  dogA.species = '貓科';   alert(dogB.species); // 顯示"犬科",不受dogA的影響
每一個實例對象,都有自己的屬性和方法的副本。這不僅無法做到資料共享,也是極大的資源浪費。

所以:繼承的思想: 透過js特有的原型鏈來實現繼承機制!

四、基於原型鏈的繼承

1.直接繼承實作

複製程式碼 程式碼如下:
var Students = function(name, age, sid) {
    Person.call(this, name, age);
    this.sid = sid;
}
Students.prototype = new Person(); //把Person放到Students的原型鏈上實作繼承機制
Students.prototype.constructor = Students;
Students.prototype.getResults = function() {
    // 得到學生的成績
}

一定不要少了Students.prototype.constructor = Students這一行! ,定義一個建構函式的時候,它預設的prototype是一個Object實例,然後prototype的constructor屬性會自動被設定成該函式本身 ! ! !若手動將prototype設定為另一個物件的時候,則新物件自然不會具有原物件的contructor值,故需要重新設定其constructor屬性。如:
複製程式碼 程式碼如下:
var Test = function() {
    this.time = "now";
}
console.log(Test.prototype); // Object {} 一個空物件
console.log(Test.prototype.constructor); // function() {this.time = "now";},及函數本身
// 若手動改變Test的prototype屬性
Test.prototype = {
    someFunc: function() {
        console.log('hello world!');
    }
};
console.log(Test.prototype.constructor); // function Object() { [native code] }
// 然後你會發現完全指錯了,故手動更改prototype屬性的時候需要更改它的constructor指向;

經過上面的測試就知道為什麼要修改constructor值了。

2.封裝繼承的函數extend

複製程式碼 程式碼如下:
function extend(subClass, superClass) {
    var F = function() {};
    F.prototype = superClass.prototype;
    subClass.prototype = new F();
    subClass.prototype.constructor = subClass;
}

其實這個函數的功能只是上面繼承過程的一個封裝,不同的有:
只繼承了superClass的prototype屬性,並沒有繼承superClass建構函式中的屬性;
這樣做的優點在於:減少去new一個建構函式的開銷!
當然隨之的問題是不能單一的通過這個函數就能讓subClass繼承superClass的所有性質
改進:
複製程式碼 程式碼如下:
// 在Students建構子中繼續加入一行程式碼:
Person.call(this, name, age);

五、小結

利用js的原型鏈原理,我們可以很容易的實作js的繼承機制,儘管不是非常的嚴格,但是我的目的達到了: 重複的程式碼盡量出現一次!

希望本文所述對大家的javascript程式設計有所幫助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1317
25
PHP教程
1268
29
C# 教程
1248
24
C++ 函式繼承詳解:如何在繼承中使用「基底類別指標」和「衍生類別指標」? C++ 函式繼承詳解:如何在繼承中使用「基底類別指標」和「衍生類別指標」? May 01, 2024 pm 10:27 PM

在函數繼承中,使用「基底類別指標」和「衍生類別指標」來理解繼承機制:基底類別指標指向派生類別物件時,執行向上轉型,只存取基底類別成員。派生類別指標指向基底類別物件時,執行向下轉型(不安全),必須謹慎使用。

C++ 函式繼承詳解:如何偵錯繼承中出現的錯誤? C++ 函式繼承詳解:如何偵錯繼承中出現的錯誤? May 02, 2024 am 09:54 AM

繼承錯誤調試技巧:確保正確的繼承關係。使用偵錯器逐步執行程式碼,檢查變數值。確保正確使用virtual修飾符。檢查隱藏的繼承帶來的菱形繼承問題。檢查抽象類別中未實現的純虛函數。

C++ 函式繼承詳解:如何理解繼承中的「is-a」與「has-a」關係? C++ 函式繼承詳解:如何理解繼承中的「is-a」與「has-a」關係? May 02, 2024 am 08:18 AM

C++函式繼承詳解:掌握「is-a」和「has-a」關係什麼是函式繼承?函數繼承是C++中一種將衍生類別中定義的方法與基底類別中定義的方法關聯起來的技術。它允許衍生類別存取和重寫基底類別的方法,從而擴展了基底類別的功能。 「is-a」和「has-a」關係在函數繼承中,「is-a」關係指派生類別是基底類別的子類型,也就是說,衍生類別「繼承」了基底類別的特性和行為。 「has-a」關係指派生類別包含對基底類別物件的參考或指針,也就是說,衍生類別「擁有」了基底類別物件。語法以下是如何實作函數繼承的語法:classDerivedClass:pu

深入了解CSS佈局重新計算與渲染的機制 深入了解CSS佈局重新計算與渲染的機制 Jan 26, 2024 am 09:11 AM

CSS回流(reflow)和重繪(repaint)是網頁效能優化中非常重要的概念。在開發網頁時,了解這兩個概念的工作原理,可以幫助我們提高網頁的回應速度和使用者體驗。本文將深入探討CSS回流和重繪的機制,並提供具體的程式碼範例。一、CSS回流(reflow)是什麼?當DOM結構中的元素發生視覺性、尺寸或位置改變時,瀏覽器需要重新計算並套用CSS樣式,然後重新佈局

C++ 中繼承和多態性如何影響類別的耦合度? C++ 中繼承和多態性如何影響類別的耦合度? Jun 05, 2024 pm 02:33 PM

繼承和多態性會影響類別的耦合度:繼承會增加耦合度,因為衍生類別依賴基底類別。多態性可以降低耦合度,因為物件可以透過虛擬函數和基底類別指標以一致的方式回應訊息。最佳實踐包括謹慎使用繼承、定義公共介面、避免在基底類別中新增資料成員,以及透過依賴注入解耦類別。實戰案例顯示如何使用多態性和依賴注入來降低銀行帳戶應用程式中的耦合度。

解釋self ::,parent ::和static :: in php oop中的區別。 解釋self ::,parent ::和static :: in php oop中的區別。 Apr 09, 2025 am 12:04 AM

在PHPOOP中,self::引用當前類,parent::引用父類,static::用於晚靜態綁定。 1.self::用於靜態方法和常量調用,但不支持晚靜態綁定。 2.parent::用於子類調用父類方法,無法訪問私有方法。 3.static::支持晚靜態綁定,適用於繼承和多態,但可能影響代碼可讀性。

'PHP物件導向程式設計入門:從概念到實踐” 'PHP物件導向程式設計入門:從概念到實踐” Feb 25, 2024 pm 09:04 PM

什麼是物件導向程式設計?物件導向程式設計(OOP)是一種程式設計範式,它將現實世界中的實體抽象化為類,並使用物件來表示這些實體。類別定義了物件的屬性和行為,而物件則實例化了類別。 OOP的主要優點在於它可以使程式碼更易於理解、維護和重複使用。 OOP的基本概念OOP的主要概念包括類別、物件、屬性和方法。類別是物件的藍圖,它定義了物件的屬性和行為。物件是類別的實例,它具有類別的所有屬性和行為。屬性是物件的特徵,它可以儲存資料。方法是物件的函數,它可以對物件的資料進行操作。 OOP的優點OOP的主要優點包括:可重複使用性:OOP可以讓程式碼更

Java 介面與抽象類別:通往程式設計天堂之路 Java 介面與抽象類別:通往程式設計天堂之路 Mar 04, 2024 am 09:13 AM

介面:無實作的契約介面在Java中定義了一組方法簽名,但不提供任何具體實作。它充當一種契約,強制實作該介面的類別實現其指定的方法。介面中的方法是抽象方法,沒有方法體。程式碼範例:publicinterfaceAnimal{voideat();voidsleep();}抽象類別:部分實作的藍圖抽象類別是一種父類,它提供了一個部分實現,可以被它的子類別繼承。與介面不同,抽象類別可以包含具體的實作和抽象方法。抽象方法是用abstract關鍵字聲明的,並且必須被子類別覆蓋。程式碼範例:publicabstractcla

See all articles