Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 多次继承,使每个实例的成员保持私有_Javascript_Oop_Inheritance - Fatal编程技术网

Javascript 多次继承,使每个实例的成员保持私有

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 = {

基本上,我想做的是,已经讨论过很多次了。然而,大多数示例只支持从ClassB继承的ClassA。我的情况很简单,但是在我找到的JavaScript主题中似乎没有提到

ClassB扩展了ClassA,后者有一个成员。ClassC和ClassD扩展了ClassB。但是,在ClassC实例中设置唯一成员时,该成员也在ClassD的成员中设置。让我们看一个例子:

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数据
不再在实例之间共享。