我在Javascript中玩弄繼承,嘗試圍繞使用Object.create創建類和子類的過程。到目前爲止,這麼好,但我遇到了一個棘手的問題。Javascript繼承,子類自己的私有變量
我有一個公共和私有變量和函數的基類。從那以後,我創建了一個具有自己的公共和私有變量和函數的「高級」類。一切都按預期工作,直到使用子類爲止,並且我嘗試從自己的私有函數中訪問自己的私有變量。
最底層A3.tellASecret()
的調用是堆棧的開始。它在AdvancedClass
之內去this.tellASecret
(如預期)。從那裏,我打電話給secretTellAdvSecret.call(this)
,使用call
,因爲我知道如果我不知道我會失去範圍。當我進入secretTellAdvSecret
時,私有變量avdPrivateVar
未定義。
在跳到結論之前,我跳進了檢查員,這裏對我來說有點奇怪。我可以看到,this
仍然是一個AdvancedClass
,這很好,但當然不能解釋任何事情,因爲我已經知道我攜帶的範圍。當我看到關閉時,我看到了我期望的一切:baseInput
& advInput
正確的值,並且secretTellAdvSecret
也在那裏......但是沒有advPrivateVar
。我明白這就是爲什麼當我到達這個點時它是不確定的,但我不明白爲什麼它不在那裏。它是在關閉中定義的,所以不應該在關閉中提供?
關於我絆倒或缺少什麼的任何想法?
var BaseClass = function(baseInput){
console.log('> new BaseClass(%s)', Array.prototype.slice.call(arguments).toString());
var basePrivateVar = (baseInput)?('(private)' + baseInput):'baseSecret';
this.basePublicVar = (baseInput)?('(public)' + baseInput):'baseNotSecret';
function secretTellBaseSecret(){
console.log('> BaseClass::secretTellBaseSecret(%s)', Array.prototype.slice.call(arguments).toString());
return basePrivateVar;
}
this.tellSecret = function(){
console.log('> BaseClass::tellSecret(%s)', Array.prototype.slice.call(arguments).toString());
var x = secretTellBaseSecret();
return secretTellBaseSecret();
};
};
BaseClass.prototype = {
tellSecret: function(){
console.log('> BaseClass.prototype.tellSecret(%s)', Array.prototype.slice.call(arguments).toString());
return this.tellSecret();
}
};
var AdvancedClass = function(baseInput, advInput){
console.log('> new AdvancedClass(%s)', Array.prototype.slice.call(arguments).toString());
BaseClass.call(this, baseInput);
var advPrivateVar = (advInput)?('(private)' + advInput):'advSecret';
this.advPublicVar = (advInput)?('(public)' + advInput):'advNotSecret';
function secretTellAdvSecret(){
console.log('> AdvancedClass::secretTellAdvSecret(%s)', Array.prototype.slice.call(arguments).toString());
return avdPrivateVar;
};
this.tellASecret = function(){
console.log('> AdvancedClass::tellSecret(%s)', Array.prototype.slice.call(arguments).toString());
return secretTellAdvSecret.call(this);
};
};
AdvancedClass.prototype = Object.create(BaseClass.prototype, {
tellBaseSecret: {
value: function(){
console.log('> AdvancedClass.prototype.tellBaseSecret', Array.prototype.slice.call(arguments).toString());
return BaseClass.prototype.tellSecret.apply(this, arguments);
},
enumerable: true
}
});
AdvancedClass.prototype.constructor = AdvancedClass;
var A1 = new BaseClass("A1's secret");
console.log("A1's secret = " + A1.tellSecret());
var A2 = new BaseClass("A2's secret");
console.log("A2's secret = " + A2.tellSecret());
console.log("A1's secret = " + A1.tellSecret());
var A3 = new AdvancedClass("A3's base secret", "A3's advanced secret");
console.log("A3's base secret = " + A3.tellSecret());
console.log("A3's base secret = " + A3.tellBaseSecret());
console.log("A3's advanced secret = " + A3.tellASecret());
看起來像一個錯字,你想引用它作爲'avdPrivateVar '......注意第二個和第三個字母的順序。 – Hargobind
avdPrivateVar只在您的代碼中出現一次,很確定它是錯誤的 – Patrick