[英]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
等等。 所以无论如何,这都是您无法控制的。
*当您根据实现使用范围变量时,其中的任何一个或大多数都不起作用:
定义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/
privateVar
是BaseClass
的局部变量。 子类不能继承或更改它。
您可以将父类和子类封装在相同的范围内,如下所示:
(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.