繁体   English   中英

Javascript:从基类继承方法并返回子类的私有变量

[英]Javascript: Inherit method from base class and return the subclass's private variable

我定义了以下BaseClass:

function BaseClass (arg1,arg2,arg3) {
    //constructor code here then - 
    var privateVar = 7500;
    this.getPrivateVar = function() { return privateVar; };
}

我想拥有以下允许更改privateVar的子类:

function SubClass (arg1,arg2,arg3,privateVar) {
    //constructor code here then - 
    var privateVar = privateVar;
}
SubClass.prototype = new BaseClass();

现在,我希望SubClass继承getPrivateVar方法。 但是,当我尝试此操作时,它总是返回7500 ,这是BaseClass中的值,而不是privateVar的值。

换句话说,是否可以继承BaseClass的公共方法,但是其中有任何引用引用SubClass的属性? 我该怎么办?


凭着声音,这是不可能的。 这个想法是为我的学生代码(我辅导孩子们)自动化一个代码检查器,但我只需要寻找另一种方法。 不管怎么说,还是要谢谢你。

您正在将Javascript对象模型与不能互操作的作用域变量混合*。

执行SubClass.prototype = new BaseClass();的继承习惯用法SubClass.prototype = new BaseClass(); 仅当您自然使用原型和构造函数时才有效:

function BaseClass(arg1, arg2, arg3) {
    this._privateVar = 7500;
}
BaseClass.prototype.getPrivateVar = function() {
    return this._privateVar;
};

function SubClass(arg1, arg2, arg3, privateVar) {

}
SubClass.prototype = new BaseClass();
//Better way to do it is 
//SubClass.prototype = Object.create(BaseClass.prototype);
SubClass.prototype.constructor = SubClass;

在您认为任何人都可以通过编写_来访问该属性之前,我可以反驳说任何人都可以通过使用反射来访问Java,PHP或C#中的任何private。 或使用instance_eval或在Ruby中send等等。 所以无论如何,这都是您无法控制的。


*当您根据实现使用范围变量时,其中的任何一个或大多数都不起作用:

  • 可数性
  • 可写性
  • 一流的访问器
  • 密封性,冻结性和延伸状态
  • 通过getPropertyNames或键进行反射
  • 运算符实例
  • 通用方法
  • 遗产

定义privateVar的方式使其成为BaseClass“构造函数”范围内的局部变量。 就像Neal所说的那样,您不能从任何继承的类继承或“看到”它。 您可以像Neal所说的那样使用闭包(但这可能会导致内存过大,具体取决于您的使用上下文),或者将变量设为实例变量:

function BaseClass (arg1,arg2,arg3) {
    //constructor code here then - 
    this.privateVar = 7500;
    this.getPrivateVar = function() { return this.privateVar; };
}

function SubClass (arg1,arg2,arg3,privateVar) {
    //constructor code here then - 
    this.privateVar = privateVar;
}

SubClass.prototype = new BaseClass();

var subClass = new SubClass(1,2,3,4000);

console.log(subClass.getPrivateVar());

具有私有变量的想法是,在声明的范围之外不能访问该私有变量 但是,有几种方法可以实现您想要的目标。 例如,您可以在BaseClass privateVar的默认值动态化:

function BaseClass(arg1,arg2,arg3) {
    var privateVar = BaseClass.privateVar;

    this.getPrivateVar = function () {
        return privateVar;
    };
}

BaseClass.privateVar = 7500;

现在,您可以按以下方式创建SubClass

function SubClass(arg1, arg2, arg3, privateVar) {
    var args = Array.prototype.slice.call(arguments, 0, 3); // the first 3 args
    var defaultPrivateVar = BaseClass.privateVar;           // save the old value
    BaseClass.privateVar = privateVar;                      // set a new default
    BaseClass.call(this, args);                             // call super
    BaseClass.privateVar = defaultPrivateVar;               // restore old value
}

SubClass.prototype = Object.create(BaseClass.prototype);    // inherit new way

现在,您只需要简单地创建SubClass的实例即可: http : //jsfiddle.net/Pytkj/

privateVarBaseClass的局部变量。 子类不能继承或更改它。

您可以将父类和子类封装在相同的范围内,如下所示:

(function(){
    var privateVar = 7500;

    function BaseClass (arg1,arg2,arg3) {
        //constructor code here then - 
        this.getPrivateVar = function() { return privateVar; };
    }

    function SubClass (arg1,arg2,arg3,privateVar) {
        //constructor code here then - 
    }

    SubClass.prototype = new BaseClass();

    return SubClass;
})();

你不会。 即使可以,也不能再将该属性称为“私有”。 也许是“受保护的”。

缺乏不同访问级别的语言仅使用公共属性和某种命名约定(例如称它们为__semiPrivateVar)。

有一些不同的解决方案,但是它们并不是真正按照OO描述的(您真正拥有的不是类和属性,而是构造函数,范围和变量)。

继承BaseClass的公共方法,但是其中有任何引用引用SubClass的属性吗?

不,那是不可能的。 BaseClass构造函数作用域内创建的方法将始终引用该作用域中的变量,您不能对其进行更改。 这是一个变量 ,而不是对象的属性

但是,您在做继承错误。 您有一个继承自其的BaseClass 实例 ,所有SubClass实例将与它们共享其getPrivateVar方法。 让他们自己一个! 为此,您可以在子实例上应用父构造函数,从而创建新的闭包作用域和新方法。 并且不要使用new

function SubClass (arg1,arg2,arg3) {
    BaseClass.call(this);
}
// or, if you need a reference to the variable:
function SubClass (arg1,arg2,arg3) {
    // you have to create it on your own
    var privateVar = arguments[3]; // or use a formal parameter
    // and create `getPrivateVar` yourself
    this.getPrivateVar = function() { return privateVar; };
}

SubClass.prototype = Object.create(BaseClass.prototype);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM