Дизайн объектов Javascript

#javascript

#javascript

Вопрос:

В Javascript я хотел бы создать два класса: узел и список узлов. Узел содержит некоторые тривиальные свойства; список узлов содержит указатели на узел, и несколько списков узлов могут содержать одни и те же узлы. Будет ли следующее правильным (упрощенным) дизайном?

 function Node(name, x, y) {
    this.name = name;
    this.x = x;
    this.y = y;
}

Node.prototype.setX = function(x) {
    this.x = x;
};

Node.prototype.setY = function(y) {
    this.y = y;
};

function Nodelist() {
    this.list = [];
}

Nodelist.prototype.addNode = function(node) {
    this.list.push(node);
};

var a = new Node('stack', 0, 0);
var b = new Node('overflow', 0, 0);
var l = new Nodelist();
var m = new Nodelist();
l.addNode(a);
l.addNode(b);
m.addNode(a);
  

Нужны ли мне вообще эти .prototype.set функции? Играя в консоли, кажется, я могу просто сделать node.x = 10 . Спасибо.

Ответ №1:

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

 function Guy(name) {
    var _name = name;

    this.getName = function(){ return _name; }
    this.setName = function(n) { _name = n; }
}

var g = new Guy("Bob");
alert(g.getName()); // works
alert(g._name); // doesn't work
  

(Фактически, в этом простом примере вам даже не нужна переменная _name ; getName и setName могут закрываться по аргументу функции name );

Ответ №2:

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

Ответ №3:

Свойства объектов Javascript доступны из любого места ie. реальных частных переменных не существует, поэтому определять методы getter setter таким образом бессмысленно. Если вам нужны частные переменные или подобное поведение, прочитайте это http://javascript.crockford.com/private.html

Комментарии:

1. false, вы можете воздействовать на частные переменные, используя функции экземпляра, которые закрываются над локальными переменными, определенными в конструкторе.

2. ДА. вот почему я упомянул реальные частные переменные , как в частных переменных, поддерживаемых в качестве языковой функции

3. спасибо, что нашли время объяснить ваше личное определение «реальных частных переменных». независимо от этого, понижающий голос остается, потому что вы основываете свое утверждение о том, что получатели / установщики бессмысленны с этой тривиальной точки зрения. методы получения / установки, безусловно, не являются бессмысленными в oojs.

4. @gWiz я согласен. я не имел в виду, что геттеры и сеттеры сами по себе бессмысленны в oojs. но то, как они используются в примере, приведенном в вопросе, бессмысленно. я изменю ответ, чтобы прояснить это

Ответ №4:

Это зависит от того, пытаетесь ли вы принудительно реализовать инкапсуляцию x и y способом ООП. Один из способов, которым javascript отличается, например, от Java, заключается в том, что он по своей сути не применяет частные переменные. Обычно распространенный способ объявить, что некоторая переменная / метод ДОЛЖНЫ быть частными, — это назвать ее с подчеркиванием. Итак, если вы на самом деле пытаетесь применить здесь концепции ООП, тогда объявите x и y следующим образом:

 function Node(name, x, y) {
  this.name = name;
  this._x = x;
  this._y = y;
}
  

А затем сохраните свои настройки. Если вы не пытаетесь принудительно применить какую-либо инкапсуляцию x и y к вашему узлу, тогда продолжайте и не предоставляйте их, а просто используйте node.x / node.y, когда вам нужно получить / установить x или y.

Просто имейте в виду, что это просто соглашение об именовании, и когда этот скрипт запущен, _x так же виден, как и x. Это будет зависеть от вас и любых программистов, с которыми вы работаете, чтобы обеспечить соблюдение этого.

Комментарии:

1. в _x и _y на самом деле нет ничего личного. смотрите мой ответ для типичного шаблона частного состояния oojs.