JavaScript: публичные методы и прототипы - PullRequest
4 голосов
/ 05 июля 2010

Я не совсем уверен, как реализовать концепции ООП в JS.

У меня есть класс, который полностью объявлен в его конструкторе:

function AjaxList(settings)
{

    // all these vars are of dubious necessity... could probably just use `settings` directly
    var _jq_choice_selector = settings['choice_selector'];
    var _jq_chosen_list = settings['chosen_list'];
    var _cb_onRefresh = settings['on_refresh'];
    var _url_all_choices = settings['url_choices'];
    var _url_chosen = settings['url_chosen'];
    var _url_delete_format = settings['url_delete_format'];

    var jq_choice_selector_form = _jq_choice_selector.closest("form");
    if (DEBUG && jq_choice_selector_form.length != 1)
    {
        throw("There was an error selecting the form for the choice selector.");
    }

    function refresh()
    {
        _updateChoicesSelector();
        _updateChosenList();
        _cb_onRefresh();
    };

    AjaxList.prototype.refresh = refresh; // will this be called on all AjaxLists, or just the instance used to call it?
    // AjaxList.refresh = refresh; // will this be called on all AjaxLists, or just the instance used to call it?

    // ...
}

Существует несколько экземпляров AjaxList,Когда я звоню refresh() одному из них, я хочу, чтобы обновлялся только этот список.В следующем случае:

term_list = AjaxList(settings);
term_list.refresh();

Вызов refresh(), кажется, заставляет все AjaxLists обновляться самостоятельно.Как правильно сделать это?

Я использую jQuery, если это имеет какое-то значение.

Ответы [ 3 ]

7 голосов
/ 05 июля 2010

Вы не должны переопределять функцию-прототип в конструкторе. Если вы хотите создать привилегированную функцию, используйте this.methodname = ... из конструктора.

function AjaxList() {
  var privateVar = 0;
  function privateFunction() {
    //...
  }
  //create a refresh function just for this instance of the AjaxList
  this.refresh = function() {
    //privileged function, it can access the 'privateVar & privateFunction'
    privateVar++;
  }
}
//public functions that don't need access to the private variables/functions
AjaxList.prototype.publicFunction=function() {

};

Также, если вы хотите создать правильный объект, вам нужно изменить

term_list = AjaxList(settings);

до

term_list = new AjaxList(settings);
3 голосов
/ 05 июля 2010
AjaxList = function(settings) {
    this._jq_choice_selector = settings["choice_selector"];
    this._jq_chosen_list = settings["chosen_list"];
    this._cb_onRefresh = settings["on_refresh"];
    this._url_all_choices = settings["url_choices"];
    this._url_chosen = settings["url_chosen"];
    this._url_delete_format = settings["url_delete_format"];

    this.jq_choice_selector_form = _jq_choice_selector.closest("form");
    if (DEBUG && jq_choice_selector_form.length != 1) {
        throw "There was an error selecting the form for the choice selector.";
    }
};

AjaxList.prototype = {
    _updateChoicesSelector: function() { },
    _updateChosenList: function() { },
    _cb_onRefresh: function() { },

    refresh: function() {
        this._updateChoicesSelector();
        this._updateChosenList();
        this._cb_onRefresh();
    }
};

Учитывая эту структуру, вы сможете позвонить:

var ajaxList = new AjaxList(settings);
ajaxList.refresh(); // etc.
2 голосов
/ 05 июля 2010

Я использую jQuery, если он делает какие-либо разница.

Нет, это не так. Смотрите мой ответ здесь: В чем разница между Javascript, Jquery и Ajax?

У меня есть класс, который полностью объявлено в его конструкторе

В Javascript нет классов . Забудь их. Вам действительно нужно изучить некоторые основы этого языка, чтобы использовать их. Это не Java, хотя выглядит похоже.

Если у вас есть Функция конструктора , она создаст экземпляр. Общие методы будут находиться в цепочке прототипов , и только данные, специфичные для экземпляра, попадают прямо в функцию с помощью это ключевое слово .

Таким образом, базовая концепция объекта будет выглядеть так:

// constructor of an instance
function MyObject( param1, param2 ) {
  this.param1 = param1;
  this.param2 = param2;
  this.param3 = 32;
  return this; // [optional]
}

// Public methods can be called by any instance.
// Instances share their prototype object.
// The this keyword always points to the current
// instance that calls the method.
MyObject.prototype.sum = function() {
  return this.param1 + this.param2 + this.param3;
}

// refresh should be a shared method, since it
// does the same thing on every instance
MyObject.prototype.refresh = function() {
  // do the refresh
  // ...
}

power этой концепции заключается в том, что в памяти имеется только одна функция обновления . И это может иметь дело с любым экземпляром. Кроме того, если другой объект наследует от MyObject, функция обновления будет унаследована . Но в памяти все еще будет одна общая функция обновления . И это может иметь дело с любым из родительских или дочерних экземпляров.

...