Javascript 多次继承,使每个实例的成员保持私有
基本上,我想做的是,已经讨论过很多次了。然而,大多数示例只支持从ClassB继承的ClassA。我的情况很简单,但是在我找到的JavaScript主题中似乎没有提到 ClassB扩展了ClassA,后者有一个成员。ClassC和ClassD扩展了ClassB。但是,在ClassC实例中设置唯一成员时,该成员也在ClassD的成员中设置。让我们看一个例子:Javascript 多次继承,使每个实例的成员保持私有,javascript,oop,inheritance,Javascript,Oop,Inheritance,基本上,我想做的是,已经讨论过很多次了。然而,大多数示例只支持从ClassB继承的ClassA。我的情况很简单,但是在我找到的JavaScript主题中似乎没有提到 ClassB扩展了ClassA,后者有一个成员。ClassC和ClassD扩展了ClassB。但是,在ClassC实例中设置唯一成员时,该成员也在ClassD的成员中设置。让我们看一个例子: function ClassA(data) { var This = this; This._data = {
function ClassA(data) {
var This = this;
This._data = {};
This._construct = function(data) {
if( undefined === data ) {
This._data = {};
return true;
}
This._data = data;
}
This._construct(data);
}
function ClassB() {
}
ClassB.prototype = new ClassA();
ClassB.prototype.constructor = ClassB;
function ClassC() { // Extends ClassB
}
ClassC.prototype = new ClassB();
ClassC.prototype.constructor = ClassC;
function ClassD() { // Extends ClassB
}
ClassD.prototype = new ClassB();
ClassD.prototype.constructor = ClassD;
var objectC = new ClassC();
var objectD = new ClassD();
objectC._data['somevar'] = 'asdasdasd';
console.log(objectC._data); // Object { somevar="asdasdasd"}
console.log(objectD._data); // Object { somevar="asdasdasd"}
如果在console.log(objectC.\u数据)行上设置断点代码>,您可以在FireBug的监视窗口中看到所有原型都已正确设置。这真的很奇怪,因为很明显ClassC和ClassD的原型是使用new
关键字创建的独立实例,因此不应该共享成员。有人能解释一下吗
\u construct()
函数可以从ClassA中删除,但不起任何作用。
可以删除var This=This
行,并且所有对This
的后续引用都可以更改为This
,而不会产生任何效果。您需要在每个类中调用super,才能使此模式正常工作。这就是你能做到的
//Simplifying the construction part a bit.
function ClassA(data) {
this._data = data || {};
}
function ClassB(data) {
ClassA.call(this, data); //call super class (ClassA) constructor
//here you can initialize any ClassB specific variables
}
ClassB.prototype = new ClassA();
ClassB.prototype.constructor = ClassB;
function ClassC(data) { // Extends ClassB
ClassB.call(this, data); //call super class (ClassB) constructor
//here you can initialize any ClassC specific variables
}
ClassC.prototype = new ClassB();
ClassC.prototype.constructor = ClassC;
function ClassD(data) { // Extends ClassB
ClassB.call(this, data); //call super class (ClassB) constructor
//here you can initialize any ClassD specific variables
}
ClassD.prototype = new ClassB();
ClassD.prototype.constructor = ClassD;
var objectC = new ClassC();
var objectD = new ClassD();
objectC._data['somevar'] = 'asdasdasd';
console.log(objectC._data); // Object { somevar="asdasdasd"}
console.log(objectD._data); // Object {} -- empty for objectD
现在您可以看到,\u数据
不在实例之间共享。问题已解决。对于那些真正想知道自己在做什么的极客,请参见。我使用jQuery,所以看起来是正确的解决方案。好吧,它是垃圾,充满了bug,看起来被作者抛弃了。相反,请查看\u data={}
和x='testmember'
之间的区别。。?我看不出有什么不同。然而,我作为评论发布到原始帖子的文章对此进行了详细解释。@XedinUnknown我只是指出,x
不是跨实例共享的,而\u数据
是跨实例共享的。区别在于\u data
是一个“对象”,而x
是一个“字符串”。再一次,我不完全确定为什么会发生这种情况。顺便说一句,你的文章很好。谢谢。在您的特定情况下,这是因为在JavaScript中,基本类型是通过值传递的,对象是通过引用传递的。然而,因为在构建或多或少复杂的应用程序时,我们需要一致的可靠行为,所以您的方法不是解决方案——仅仅因为它不是一种方法。如果我需要一个对象,我不能只使用一个原语。@XedinUnknown,我知道了。我相应地更新了答案,加入了对super
的调用。您现在可以看到,\u数据
不再在实例之间共享。