2013-08-19 92 views
2

我正在使用JavaScript中的類繼承方法之一(正如我正在修改的代碼中使用的那樣),但不理解如何將子類中的方法的附加功能附加到相應父類方法的功能已經有了;換句話說,我想用一個方法覆蓋子類中的父方法,除了它自己的子類特定的東西外,父方法也是這樣做的。所以,我試圖從孩子的方法調用父母的方法,但它甚至有可能嗎?如何從JavaScript中的子類調用父類的方法,以便可以訪問父類的局部變量?

代碼在這裏:http://jsfiddle.net/7zMnW/。請打開開發控制檯查看輸出。這裏還

代碼:

function MakeAsSubclass (parent, child) 
{ 
    child.prototype = new parent; // No constructor arguments possible at this point. 
    child.prototype.baseClass = parent.prototype.constructor; 
    child.prototype.constructor = child; 

    child.prototype.parent = child.prototype; // For the 2nd way of calling MethodB. 
} 

function Parent (inVar) 
{ 
    var parentVar = inVar; 

    this.MethodA = function() {console.log("Parent's MethodA sees parent's local variable:", parentVar);}; 
    this.MethodB = function() {console.log("Parent's MethodB doesn't see parent's local variable:", parentVar);}; 
} 

function Child (inVar) 
{ 
    Child.prototype.baseClass.apply(this, arguments); 

    this.MethodB = function() 
    { 
     console.log("Child's method start"); 
     Child.prototype.MethodB.apply(this, arguments); // 1st way 
     this.parent.MethodB.apply(this, arguments); // 2 2nd way 
     console.log("Child's method end"); 
    }; 
} 

MakeAsSubclass(Parent, Child); 

var child = new Child(7); 
child.MethodA(); 
child.MethodB(); 
+0

不,你不能看到父母的本地變量。你繼承了父母的原型鏈,而不是他們的本地狀態。 –

回答

4

不,你不能看到父母的局部變量。你繼承了父母的原型鏈,而不是他們的本地狀態。在你的情況下,你將父函數應用到不包含狀態的子對象上。

apply(this,...) 

意味着您將函數綁定到當前值。當您從子對象調用方法b時,它將綁定到子對象,因此不在包含父對象值的閉包中操作。

+0

但是Parent的MethodA(從子對象調用)確實看到變量。我想這是因爲它是在其構造函數中爲孩子重新創建的。但是,MethodB沒有。 –

+0

您正在對父對象調用A。你在一個子對象上調用B.如果你打電話給A(這個),它也會失敗 –

+0

好的,對我來說似乎很奇怪。 :)我的意思是,我做'child.MethodA();',但事實證明我實際上是在父對象上調用MethodA! –

0

變量var parentVar = inVar;是一個本地和私有變量,僅在Parent()函數中可用,並且僅對在同一範圍(Parent())中定義的函數可見。

我認爲最好的方法在這裏是修改父類以這樣一種方式使parentVar不會是私人的,但市民:

function Parent(inVar) { 

    this.parentVar = inVar; 

} 
2

我會建議使用這樣的私有實例值的屬性agains因爲它弄亂了原型。需要訪問私有實例變量的函數(每個實例都有自己的私有值)不能放在原型上,所以你不能真正使用它。

下面是你的代碼可以工作(但我不會做我自己):

var Parent = function(){ 
    var private=22; 
    this.showPrivate=function(){ 
    console.log(private); 
    } 
} 
var Child=function(){Parent.call(this)}; 
// the following is only usefull if you have functions 
// on the parent prototype that don't use privates 
Child.prototype=Object.create(Parent.prototype); 
// Child.prototype.constructor would now point to Parent 
// it's not needed most of the time but you can fix that 
Child.prototype.constructor=Child; 

var c = new Child(); 
c.showPrivate(); 

這裏是你如何使用「私有」的功能:在構造

var Parent = function(name){ 
    //public instance variable 
    this.name=name; 
} 
Parent.prototype=function(){ 
    // privates on the prototype (shared among instances) 
    var privateFunction=function(me){ 
    console.log("private function called in:"+me.name); 
    console.log("shared in "+me.name 
     +" is now:"+shared+" setting it to 'changed'"); 
    shared="Changed"; 
    } 
    // private shared value 
    var shared="Parent" 
    return{ 
    constructor:Parent, 
    publicFn:function(){ 
    privateFunction(this); 
    } 
    }; 
}(); 

var Child=function(name){Parent.call(this,name)}; 
Child.prototype=Object.create(Parent.prototype); 
Child.prototype.constructor=Child; 

var c = new Child("child1"); 
var c2 = new Child("child2"); 
c.publicFn(); 
c2.publicFn();//shared is already changed by 'child1' 

更多信息功能here

+0

感謝您對私有函數和私有靜態/共享變量的參考!但是關於私有實例值:你的例子與我的不同之處究竟是什麼? 「showPrivate」函數看起來很像我的「MethodA」,它可以訪問本地變量。這是「MethodB」,我遇到了問題。 –

+0

@Janis我不知道,不知道你的代碼應該做什麼。從你的問題的描述我試圖張貼代碼,顯示如何重寫父函數。使用私有實例值屬性的示例(構造函數體中的所有內容)我想這不會顯示覆蓋,因爲我從不使用它。我想你可以保存父母的功能,然後在Child's body中調用Parent.call(this)之前調用它。 – HMR

相關問題