1. 程式人生 > 實用技巧 >node.js面向物件實現(二)繼承

node.js面向物件實現(二)繼承

>>> hot3.png

繼承是面向物件中非常重要的一個概念,那麼在Node.js中如何實現繼承呢?
node.js在util中提供了inherits函式用於基於原型的繼about:ntab承,實現如下:
node.js面向物件實現(二)繼承
利用Object.create方法建立了一個具有指定原型的物件,並且指定的原型就是傳入的父類引數的原型,所以大家普遍稱這種方式為原型繼承。

我們來嘗試一下
baseClass內容:
node.js面向物件實現(二)繼承

extendClass內容:
node.js面向物件實現(二)繼承

這樣就實現了從Base到Extend的繼承,是不是非常簡單呢?我們來使用一下吧~~

呼叫:
node.js面向物件實現(二)繼承

node.js面向物件實現(二)繼承

奇怪的事情發生了!分別呼叫了父類的兩種showName的方法,但是為什麼第二種會報錯呢?仔細看一下baseClass中的定義,可以發現:

(1) 定義在建構函式內部的方法
this.showName = function()
{
console.log(this.name);
};
(2) 原型方法
Base.prototype.showName1 = function()
{
console.log(this.name1);
};
node.js自帶的inherits是無法繼承非原型方法和屬性的,也就是說在父類建構函式內部定義的方法和屬性子類中都無法得到繼承,只有父類中的原型方法和屬性才可以被子類繼承(其實從原始碼中就可以看出,inherits方法其實只複製了原型鏈而已)。那麼我們如何實現內建屬性和方法的繼承呢?

我們先來理解一下建構函式內建屬性和方法的本質
JS中this指標的本質是上下文物件的概念,其作用是在一個函式內部應用呼叫它物件的本身,那麼我們只要將父類的上下文物件完全的複製給子類不就可以讓子類呼叫父類建構函式中的內建屬性和物件了嘛~~~
JS非常強大可以使用Call方法來進行方法執行時上下文的替換,所以修改ExtendClass,在建構函式中增加一句神奇的程式碼:
node.js面向物件實現(二)繼承
Base.call(this)的作用為
(1)在Extend中執行了Base的建構函式
(2)執行base建構函式的時候其實真正的上下文物件為Extend的上下文物件
所以可以理解為在Extend的上下文物件中建立了Base建構函式中的所有屬性和方法(如果無法理解我說的,大家下個斷點走一下就可以完全明白了)

現在我們再來執行一下之前的呼叫:
node.js面向物件實現(二)繼承

可以看到我們即繼承了base中的原型方法和屬性,同時也可以訪問到base的內建屬性和方法了!!!
至此node.js面向物件中的繼承就全部講完啦~~~以上是node.js官方的繼承方式,唯一的問題就是我們不但需要呼叫util.inherits來繼承原型鏈,還需要呼叫父類的call來構造父類的內建方法和屬性。

網上還流傳著另外一種實現繼承的方式,比官方的方法更為完善一些,而且只需要呼叫一行就可以了~~
如下圖:
node.js面向物件實現(二)繼承

這種方式可以同時繼承父類的原型方法以及內建方法!還少了一句程式碼~~
其本質是將Extend的原型鏈連向Base的原型物件(new 方法的本質可以詳見我上一篇文章)。至於這種方法有和不好。。還沒有發現~~有待大牛指正~~

轉載於:https://my.oschina.net/mifans/blog/838235