不少C#或C++開發人員習慣使用繼承來開發項目,因此當他們想學習JavaScript語言時,第一個問題通常是:「我怎麼在JavaScript中使用繼承?」。javascript
實際上JavaScript使用了一種不一樣於C#或C++的方法來建立面向對象語言。它是基於prototype的語言。原型概念代表行爲是能夠經過clone已經存在的對象來做爲原型複用的。在JavaScript中每一個對象都有原型,它定義了一系列對象可使用的方法和成員。沒有class,只有對象。每個對象能夠做爲另外一個對象的原型。java
這個概念是很是靈活的,咱們能夠用它來模擬OOP繼承。程序員
讓咱們想象咱們使用JavaScript建立這個層次機構:函數
首先咱們能夠簡單地建立ClassA。由於沒有明確的類,咱們只需建立一個函數定義一組行爲:工具
var ClassA = function(){ this.name = "class A"; }
使用new 關鍵字來實例化這個「類」:學習
var a = new ClassA(); ClassA.prototype.print = function(){ console.log(this.name); }
而後使用對象來使用它:this
a.print()
很簡單,對吧?spa
完整的樣式只用了8行代碼:prototype
var ClassA = function() { this.name = "class A"; } ClassA.prototype.print = function() { console.log(this.name); } var a = new ClassA(); a.print();
如今讓咱們來建立類之間的「繼承」。這個工具只作一件簡單的事:克隆原型:code
var inheritsFrom = function(child, parent) { child.prototype = Object.create(parent,prototype); };
奇蹟發生了!經過clone原型,咱們將全部成員和函數傳給新類。
因此若是咱們想添加第一個類的子類,只須要使用這段代碼:
var ClassB = function() { this.name = "class B"; this.surname = "I'm the child"; } inheritsFrom(ClassB, ClassA);
因此ClassB繼承了ClassA的print函數,因此下面代碼是有效的:
var b = new ClassB(); b.print();
因此產生如下輸出:
class B
咱們甚至能夠覆蓋ClassB的print函數:
ClassB.prototype.print = function(){ ClassA.prototype.print.call(this); console.log(this.surname); }
在這種狀況下,輸出是這樣的:
class B
I’m the child
這裏的技巧是調用ClassA.prototype來獲取print函數。因爲call函數咱們能夠對當前對象(this)調用基本函數。
建立ClassC是顯而易見的:
var ClassC = function () { this.name = "class C"; this.surname = "I'm the grandchild"; } inheritsFrom(ClassC, ClassB); ClassC.prototype.foo = function() { // Do some funky stuff here... } ClassC.prototype.print = function () { ClassB.prototype.print.call(this); console.log("Sounds like this is working!"); } var c = new ClassC(); c.print();
輸出:
class C I’m the grandchild Sounds like this is working!
總結
最後,我想說明JavaScript不是C#或C++。它有本身的哲學。若是你說C++或C#程序員,而且你真的很想了解JavaScript全部精華,我給你最好的提示:不要試圖將你的語言複製到JavaScript。沒有最好的語言或最差的語言。只是不一樣的哲學!
連接: http://www.sitepoint.com/simple-inheritance-javascript/