Javascript继承,子类自己的私有变量

时间:2015-04-16 22:01:43

标签: javascript

我在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());

1 个答案:

答案 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
};