這里介紹的是ES6之前的繼承方式,沒有寫 class 繼承哦。
什么是繼承
繼承是指一個對象直接使用另一對象的屬性和方法。
js中繼承的方法有:原型鏈繼承、構造函數繼承、組合繼承、原型式繼承、寄生式繼承、寄生式組合繼承
1. 原型鏈繼承
(1). 原型、構造函數和實例的關系
function Person() { } Person.prototype var p = new Person();
構造函數:Person
屬性:prototype => 指向原型對象
原型對象:Person.prototype
屬性:constructor => 指向構造函數
原型、構造函數和實例的關系:

出現上面那個結果的原因是,實例是沒有constructor這個屬性的,p.constructor其實是訪問的p.prototype.constructor,但是由于我們用對象字面量的方式重寫了Person.prototype,所以會順著原型鏈往上找,找到
Object.prototype.constructor.

(2). 原型鏈
如(1)中所示,如果讓(1)中的原型對象成為另外一個類型的實例,以此類推,便構成了原型鏈。
注意:所有構造函數的默認原型都是Object的實例,因此默認原型會有一個prototype指針指向Object.prototype。
(3). 原型鏈繼承
主要思想是:通過設定一種類型的原型是另一種類型的實例來繼承另外一種類型。
例如:B要繼承A
創建A的實例:new A();
讓其等于B的原型:B.prototype = new A(); //B則繼承了A里面所有的屬性和方法
原型搜索機制:以讀取方式訪問一個實例屬性時,在該實例中搜索該屬性,若沒有找到再搜索實例的原型,順著原型鏈往上找。
代碼示例如下:

原型繼承的缺點:
(1).超類型中有引用類型(color是一個數組)的屬性時,子類型繼承超類型,一個子類型中對該引用類型修改,會反應到所有的子類型上。所有子類型共享超類型的引用類型.
例如:

(2).創建子類型實例時無法向超類型的構造函數中傳遞參數
2. 構造函數繼承
利用call()和Apply()方法在新的對象上執行超類型的構造函數。
超類型:指的是被繼承的類型。
a.func.call(b) /*指的是a對象的方法應用到b對象上*/ a.func.apply(b) // 主要是參數的區別
代碼示例:

構造函數繼承的優點:
使子類Child在創建對象的同時傳遞參數到父類Parent
構造函數繼承的缺點:
無法進行函數的復用,a的原型中定義的方法也無法繼承。
3. 組合繼承(將原型鏈繼承和借用構造函數繼承組合起來)
主要思想是:使用原型鏈實現對a原型屬性和方法的繼承,通過構造函數實現對a實例屬性的繼承。
代碼示例如下:

缺點:要調用兩次超類型的構造函數(注釋的兩個地方)
4. 原型式繼承
主要思想是:實現對父類的淺復制,產生一個副本
Object.create()函數實現的就是原型式繼承
代碼示例如下:

這種繼承方式是將child的原型設為parent,通過child可以訪問parent的屬性和方法,而不需要將同名屬性和方法在child里面再重新定義一遍。
Object.create() 可接收兩個參數,第一個參數是需要繼承的對象,第二個參數是新生成的對象中新增加的屬性和方法。

5. 寄生式繼承
主要思想:寄生式繼承是基于原型式繼承,創建一個僅用于封裝繼承的函數
代碼示例如下:

歡迎關注。