Прототип для частных суб-методов - PullRequest
0 голосов
/ 02 апреля 2012

У меня есть код, который выглядит так:

var baseClass = function() {
// CODE
    var subClass = function() {
        // MORE CODE
    }
}

Добавление методов в baseClass - это нормально, я просто использую

baseClass.prototype.newMethod = function () {
    // NEW CODE
}

Мой вопрос: как мне добавить методы в подкласс? Является ли единственный способ сделать его публичным?

######## РЕДАКТИРОВАТЬ ##############

ОК, поэтому я переставил код так, чтобы подкласс находился вне базового класса. Я передаю baseClass, чтобы subClass все еще мог обращаться к свойствам экземпляра baseClass.

var baseClass = function() {
    var base = this;
    this.property_a = 1;
    this.property_b = 5;

    var sub = new subClass(base);
    // CODE
}

var subClass = function(parent) {
    var sub = this;
    this.property_c = 1;
    this.method_a = function() {
        return sub.property_c + parent.property_a;
    }
    // MORE CODE
}

это нормально и работает, но теперь у меня появилась новая проблема, когда я добавляю метод с использованием прототипа:

subClass.prototype.method_b = function(){
    return sub.property_c + parent.property_b;
}

Я получаю сообщение о том, что родитель не определен.

По сути, у меня есть довольно простое веб-приложение, которое имеет две стороны: сторону просмотра и сторону редактирования. Я создаю базовый класс, который включает в себя все необходимое для просмотра, и я хочу добавить методы, необходимые для редактирования, в другой файл, чтобы они загружались только тогда, когда пользователь находится на странице редактирования.

Ответы [ 3 ]

1 голос
/ 02 апреля 2012

Вам нужно будет определить методы в том же контексте, в котором вы определили subClass:

var baseClass = function() {
    // CODE
    var subClass = function() {
        // MORE CODE
    }
    subClass.prototype.newMethod = function () { ... }
}

Если это невозможно, вам нужно будет выставить subClass в соответствующем контексте или предоставитьмеханизм от baseClass до subClass.

1 голос
/ 02 апреля 2012

Почему вы объявляете этот подкласс в базовом классе? Не имеет смысла для меня.

Вы можете добавить к прототипу подкласса, где бы он ни находился. В вашем коде это будет

var baseClass = function() {
// CODE
    var subClass = function() {
        // MORE CODE
    }
    subClass.prototype = {
        ...
    }
}

Но я бы предложил исключить его из конструктора базового класса. Если вы хотите, чтобы это было конфиденциально по какой-то причине, добавьте закрытие:

(function(){

    baseClass = function() { // public
        // CODE
    }
    baseClass.prototype = {...};

    var subClass = function() { // private
        // MORE CODE
    }
    subClass.prototype = Object.create(baseClass.prototype);
    subClass.prototype.newMethod = function () { ... }
})()

РЕДАКТИРОВАТЬ, чтобы ответить на расширенный вопрос:

Ах, подкласс не наследуется от базового класса! Мы ожидали, что в противном случае это может быть нормально, чтобы это было внутри конструктора. Затем один и тот же прототип мог быть добавлен к каждому из различных конструкторов подкласса:

var subproto = {
    method_b: = function(){
        // manipulate "this"
    },
    ...
};
function baseClass() {
    // some code
    function sub() {
        // is a constructor for subs which belong to this specif base intance
        ...
    }
    sub.prototype = subproto; // the sub constructors of each base instance
                              // have the same prototype
    var x = new sub(),
        y = new sub(); // example usage of the sub constructor
}
baseClass.prototype = {...}

Иначе, если вам нужен один общий вспомогательный конструктор (вне функции baseClass), вы можете указать базовому экземпляру, к которому принадлежит sub, в качестве аргумента для конструктора - как вы и сделали. Конечно, sub (как внутренние, так и внешние методы) могут получить доступ только к открытым свойствам этого базового экземпляра.

Ошибка, которую вы допустили в переставленном коде, заключается в том, что ваши прототипные («внешние») методы пытались получить доступ к закрытой переменной parent из вспомогательного конструктора. Как вы говорите, «ошибка в том, что родитель не определен».

var subClass = function(parent) {
    var sub = this;
    this.parent = parent; // make it public
    this.property_c = 1;
    this.method_a = function() {
        return sub.property_c + parent.property_a;
    }
    // MORE CODE
}
subClass.prototype.method_b = function(){
    // prototype functions can only access public properties
    // i.e. privileged methods, public attributes and other prototype properties
    return this.property_c + this.parent.property_b;
}
0 голосов
/ 02 апреля 2012

Если вы действительно хотите сохранить подкласс закрытым, вы можете скрыть определения в закрытии:

var BaseClass = (function() {
    function BaseClass() { ... };
    function SubClass() { ... };
    BaseClass.prototype.foo = function() { ... };
    SubClass.prototype.foo = function() { ... };
    return BaseClass;
})();

Лично я обнаружил, что такого рода защита с принудительным замыканием доставляет больше хлопот, чем стоит (например, затрудняет отладку) ... Но если вы захотите это сделать, вы так и сделаете.

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