2013-04-08 75 views
7

類繼承請看看下面的例子:呼叫基類的功能 - 在JavaScript

MyBaseClass = function(a) { 
    this.a = a; 
}; 

$.extend(MyBaseClass.prototype, { 
    init: function() { 
     console.log('I am initializing the base class'); 
    } 
}); 

MyChildClass = $.extend(MyBaseClass, { 
    init: function() { 
     MyBaseClass.prototype.init(); 
     console.log('I am initializing the child class'); 
    } 
}); 

var = new MyChildClass(); 
var.init(); 

Тhis應同時輸出「我初始化基類」和「我初始化子類」。

我需要能夠繼承MyBaseClass類,但仍然能夠在新的init()方法開始時調用他的init()方法。

我該怎麼做?

+3

'$ .extend'不符合你的想法。 – 2013-04-08 09:48:35

+1

這個代碼的一個明顯問題是在底部使用'var' – 2013-04-08 09:49:57

+3

反正'$ .extend'是什麼? – 2013-04-08 09:51:13

回答

17

jQuery's extend不構建繼承,但是「將兩個或多個對象的內容合併到第一個對象中」

使用prototype based inheritance實現自己的繼承和顯式調用 「超級」 的方法:

MyBaseClass = function(a) { 
    this.a = a; 
}; 
MyBaseClass.prototype.init = function() { 
    console.log('I am initializing the base class'); 
}; 

MyChildClass = function(a) { 
    this.a = a; 
} 
MyChildClass.prototype = Object.create(MyBaseClass.prototype); // makes MyChildClass "inherit" of MyBaseClass 
MyChildClass.prototype.init = function() { 
    MyBaseClass.prototype.init.call(this); // calls super init function 
    console.log('I am initializing the child class'); 
}; 

var child= new MyChildClass(); 
child.init(); 

Output

I am initializing the base class 
I am initializing the child class 
+0

這裏應該使用'Object.create'嗎? – 2013-04-08 09:55:17

+0

正如OP所說的「類」和繼承,我個人覺得原型更適合。 – 2013-04-08 09:55:59

+2

也許Jan打算使用'MyChildClass.prototype = Object.create(MyBaseClass.prototype);'。這將是一個更好的方法來繼承恕我直言。實例化父*的新實例可能有缺點。 – 2013-04-08 10:27:29

1

jsFiddle Demo

夫婦的事情。 extend真的只是增加了屬性,它並沒有太大的作用。因此,您需要爲您的類準備好一個函數,從基類繼承,然後在該類原型上使用擴展。

function MyChildClass(){}; 
MyChildClass.prototype = new MyBaseClass(); 
$.extend(MyChildClass.prototype, { 
init: function() { 
    MyBaseClass.prototype.init(); 
    console.log('I am initializing the child class'); 
} 
}); 

這裏是我喜歡用繼承的另一種方法 - 當的方法特異性將是一個問題 - 這是基類存儲在其自己的財產

function MyChildClass(){}; 
MyChildClass.prototype = new MyBaseClass(); 
MyChildClass.prototype.base = new MyBaseClass(); 
$.extend(MyChildClass.prototype, { 
init: function() { 
    this.base.init(); 
    console.log('I am initializing the child class'); 
} 
}); 
1

另一個基於原型模式來實現這一目標:

MyBaseClass = function(a) { 
    this.a = a; 
}; 

MyBaseClass.prototype = { 
    init: function() { 
     console.log('I am initializing the base class'); 
    } 
}; 

MyChildClass = function() {}; 
MyChildClass.prototype = $.extend(new MyBaseClass(), { 
    init: function() { 
     this.super.init.call(this); 
     console.log('init child'); 
    }, 
    super: MyBaseClass.prototype, 
    constructor: MyChildClass 
}); 

var a = new MyChildClass(); 
a.init(); 

輸出:

I am initializing the base class 
init child 

這裏this.super存儲對基類的引用。

+0

誠實的問題:你爲什麼要指定構造函數? – 2013-04-08 09:59:25

+0

@dystroy - 我在jquery源代碼中看到了。我認爲這是因爲有時候,構造函數有時會指向錯誤的函數(現在不記得確切的場景來讓它執行此操作)。 – 2013-04-08 10:00:37

+0

@dystroy能夠使用'instanceof'。 'MyChildClass的一個實例' – dfsq 2013-04-08 10:01:45