Наследование более одного раза с сохранением приватности членов - PullRequest
0 голосов
/ 11 октября 2011

В основном то, что я пытаюсь сделать, это то, что уже обсуждалось много раз.Однако в большинстве примеров только ClassA наследуется от ClassB.Моя ситуация довольно тривиальна, но, похоже, она не рассматривается в темах 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._data);, вы можете увидеть в окне Watch FireBug, что все прототипы установлены правильно.Это действительно странно, потому что ясно, что прототипы ClassC и ClassD - это отдельные экземпляры, созданные с помощью ключевого слова new, и поэтому они не должны совместно использовать членов.Может кто-нибудь объяснить, пожалуйста?

Функция _construct() может быть удалена из ClassA, без эффекта.Строка var This = this может быть удалена, и все последующие ссылки на This могут быть изменены на this, без эффекта.

1 Ответ

0 голосов
/ 11 октября 2011

Вам нужен вызов 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

Теперь вы видите, что _data не распределяется между экземплярами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...