有關JS”類“的繼承的必知必會基礎知識介紹

首先要說明:JS並沒有類(class)的概念,雖然說ES6開始有瞭類的概念,但是,ES6中的類,僅僅隻是基於現有的原型繼承的一種語法糖。

一、面向對象思想

在這裡我就隻說說關於面向對象的一些基本知識:

:定義某一事物的抽象特點,具有屬性和方法。簡單的理解來說:類好比一個黑盒子,你不需要知道裡面的功能,就可以使用它。舉個栗子:一臺空調,你隻需要知道上面的按鈕有什麼用,就可以使用這臺空調,完全不需要知道這臺空調裡面到底是怎麼工作的。對象:類的一個實例。例如:var myDate = new Date(); //myDate就是通過new關鍵字,創建的一個對象。它就是系統中的"類":Date()的一個實例;屬性:對象的特征;方法:對象的行為;封裝性:隻有特定類的對象才能訪問特定類的成員;繼承性:子類繼承父類的屬性和方法;多態性:不同的類可以定義相同的屬性和方法;抽象性:(就是類這個概念很抽象咯,\滑稽)

二、類的屬性和方法的繼承

糾正一下:由於JS並沒有類(class)的概念,更多的時候我們把它叫做對象(function),然後把對象叫做實例(instance)。出去和別人討論oop時,一定要叫對一些概念的名字,免得貽笑大方。

在這裡我就直接用類(class)這個叫法。

1、屬性的繼承:

1.先來看一個小例子:

function show() {
    alert(this);
}
show();  //[object window]    //很顯然輸出window對象

2.再來看一下:

function show() {
    alert(this);
}
show.call(123);  //123

這是因為函數調用call()方法時,第一個參數會覆蓋函數中的this。也就是說,這裡123把this覆蓋瞭。這是call()方法的一個用法。

有關call()的詳盡使用大傢可以自行百度,這裡就不介紹瞭。

3.繼續介紹,剛步入正題:

function A() {
    this.aaa = 111;
}
var objA = new A();
alert(objA.aaa);  //111

通過類: A 創建一個對象: objA ,所以對象: objA 就具有瞭aaa這個屬性。

4.終於說到繼承屬性瞭:

function A() {
    this.aaa = 111;
}
function B() {
    A.call(this);
}
var objB = new B();               
alert(objB.aaa);  //111    //實現繼承屬性

解釋一下:通過類: B 創建對象: objB 後,類: B中的this指向objB,這時候A.call(this)就相當於A.call(objB),正如前面所說,objB會覆蓋類: A 中的this,所以objB就具有瞭aaa屬性,所以就實現瞭屬性的繼承。

2、方法的繼承:

1.簡單的寫法:

function A() {}
function B() {}

A.prototype.showA = function () {
    alert('aaa');  
};

B.prototype = A.prototype;

var objA = new A();
var objB = new B();

objB.showA();  //aaa    //證明 B 確實繼承瞭 A 的方法

但是這種方法雖然簡單,但是有個很大的缺陷,實際上:B.prototype 是對 A.prototype 的引用。

下面我們來證明這一點:在上述代碼 B.prototype = A.prototype; 這行代碼後面添加:

B.prototype.showB = function () {
    alert('bbb');
};

然後 objA.showB(); //bbb //這就證明,B.prototype確實是對A.prototype的引用。

2.避免引用

function A() {}
function B() {}

A.prototype.showA = function () {
    alert('aaa');
};

//用for...in...循環,將A的屬性一一賦給B,這樣就不會造成B.prototype對A.prototype引用
for (let i in A.prototype) {
    B.prototype[i] = A.prototype[i];
}
		
B.prototype.showB = function () {
    alert('bbb');
};
		
var objA = new A();
var objB = new B();

objB.showA();  //aaa    //證明B繼承瞭A的方法
objA.showB();  //error    //證明A上並沒有showB方法,說明A沒有被引用

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *