Javascript-прототип и проблемы с доступом к классу - PullRequest
7 голосов
/ 14 мая 2011
Family = function(name) {
  this._Name = name;
}

Family.prototype = {
  getName: function() {
    return this._Name;
  },
  People: function(num) {
    this._Number = num;
  }
}

Family.People.prototype = {
  clearNumber: function() {
    this._Number = 0;
  }
}

Люди - это вложенный класс.Его родительский класс - Family.

Я получаю сообщение об ошибке, что Family.People не определено.Может ли кто-нибудь исправить приведенный выше код?

Ответы [ 3 ]

7 голосов
/ 14 мая 2011

Рабочий код

// function doesn't need "new" operator
var Family = function(name) { this._Name = name; };

Family.prototype = {
    getName: function() { return this._Name; }, // missing comma
    People: function(num) {
        this._Number = num;
    }
};

// work with prototypes
Family.prototype.People.prototype = {
    clearNumber: function() { this._Number = 0; }
};

Это будет работать.Но вы должны знать, что когда вы вызываете:

var f = new Family("Doe");

f.People, это просто конструктор объекта, а не экземпляр какого-либо другого объекта.Вам также нужно будет создать его экземпляр, например:

f.members = new f.People(3);

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

Лучший подход

Так что это будетвероятно, будет лучше, если вы напишите свои прототипы следующим образом:

var Family = function(name) {
    this._Name = name;
    this.getName = function() { return this._Name; };
};

Family.People = function(num) {
    this._Number = num;
    this.clearNumber = function() { this._Number = 0; };
};

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

var f = new Family("Doe");
f.members = new Family.People(3);

Детализация экземпляра f будет выглядеть следующим образом:

f
  _Name
  getName()
  members
    _Number
    clearNumber()

Личные переменные

var Family = function(name) {
    var _name = name;
    this.getName = function() { return _name; };
};

Family.People = function(num) {
    var _num = num;
    this.getNumber = function() { return _num; }
    this.clearNumber = function() { _num = 0; };
};

ThisТаким образом, мы делаем переменные приватными и доступными только внутри, чтобы ими нельзя было манипулировать снаружи.Вы должны всегда использовать функции, чтобы манипулировать ими.Это делает его более надежным, особенно когда существуют определенные бизнес-правила, связанные со значениями переменных.

var f = new Family("Doe");
f._name; // this is undefined because "_name" is private closure variable

Развертывание экземпляра f теперь будет выглядеть больше как экземпляр объекта класса:

f
  getName()
  members
    getNumber()
    clearNumber()
5 голосов
/ 14 мая 2011

Обратите внимание, что вы назначаете Family.prototype.People, а затем пытаетесь получить доступ к Family.People.

Family не является экземпляром из Family, поэтому у него нет свойств этого класса - Family является экземпляром Function, поэтому вы пытаетесь получить доступ к Function.prototype.People в этом третьем утверждении. (это немного упрощение)

т.е. что вы хотите делать, это

Family.prototype.People.prototype = {
  clearNumber:function(){this._Number = 0;}
}

Вы также пропускаете запятую перед людьми, но я предполагаю, что это опечатка ...

0 голосов
/ 14 мая 2011

Вы должны объявить конструктор People как ключ в объекте Family:

Family.People = function(num) {
  this._Number = num;
}

Прототип Family будет находиться в цепочке прототипов для новых объектов типа Family;не является частью самой семьи.

...