我正在研究 Javascript 中的继承,尝试着用 Object.create 创建类和子类。到目前为止,一切顺利,但我遇到了症结。
我有一个带有一些公共(public)和私有(private)变量和函数的基类。由此,我创建了一个“高级”类,具有自己的公共(public)和私有(private)变量和函数。一切都按预期工作,直到使用子类,并且我尝试从其自己的私有(private)函数内部访问其自己的私有(private)变量。
调用A3.tellASecret()
最底部是堆栈的开始。它转到this.tellASecret
里面AdvancedClass
(如预期)。从那里,我调用secretTellAdvSecret.call(this)
,使用call
因为我知道如果不这样做我就会失去范围。当我进去时secretTellAdvSecret
,私有(private)变量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());
最佳答案
您的代码中似乎有一个拼写错误:
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
};
关于Javascript继承,子类自己的私有(private)变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29686761/