我在Javascript中使用继承,尝试使用Object.create创建类和子类。到目前为止,这么好,但我遇到了一个棘手的问题。
我有一个带有一些公共和私有变量和函数的基类。从那以后,我创造了一个先进的"具有自己的公共和私有变量和函数的类。在使用子类之前,一切都按预期工作,我尝试从自己的私有函数中访问自己的私有变量。
最底层的A3.tellASecret()
调用是堆栈的开始。它转到this.tellASecret
AdvancedClass
内(正如预期的那样)。从那里开始,我使用secretTellAdvSecret.call(this)
拨打call
,因为我知道如果我不这样做,我将失去范围。当我进入secretTellAdvSecret
时,私有变量avdPrivateVar
未定义。
在得出结论之前,我跳进了检查员,这里对我来说有点奇怪。我可以看到this
仍然是AdvancedClass
,这很好,但当然无法解释任何事情,因为我已经知道我正在携带范围。当我看着封口时,我看到了我所期待的一切:baseInput
& advInput
具有正确的值,secretTellAdvSecret
也在那里......但是没有advPrivateVar
。我明白了为什么当我达到这一点时(dh)它是不确定的,但我不明白它为什么不存在。它是在闭包内定义的,所以它不应该在闭包内可用吗?
关于我绊倒或丢失某些东西的任何想法?
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());
答案 0 :(得分:1)
您的代码中似乎有拼写错误:
function secretTellAdvSecret(){
console.log('> AdvancedClass::secretTellAdvSecret(%s)', Array.prototype.slice.call(arguments).toString());
return avdPrivateVar; // typo
};
更改为:
function secretTellAdvSecret(){
console.log('> AdvancedClass::secretTellAdvSecret(%s)', Array.prototype.slice.call(arguments).toString());
return advPrivateVar; // this line
};