Ответ 1
Исходя из фона в Java и PHP, я изначально боролся со всей концепцией класса в javascript. Вот несколько вещей, о которых нужно подумать:
Строительство
Во-первых, поскольку вы, вероятно, будете определять свои классы как..
Customer = function () {}
Customer.prototype = new Person();
В конечном итоге вы столкнетесь со всеми кошмарами кода, если вы определяете свойства и методы во время построения. Причина заключается в том, что кусок кода, например Customer.prototype = new Person();
, требует, чтобы Person вызывался в конструкторе Customer для истинного наследования.. в противном случае вам будет нужно знать, что изначально устанавливается в оригинале. Возьмем следующий пример:
Person = function (name) {
this.name = name;
this.getName = function () {return this.name}
}
Customer = function (name) {
this.name = name;
}
Customer.prototype = new Person();
Теперь мы собираемся обновить Person, чтобы установить, являются ли они "новыми":
Person = function (name, isNew) {
this.name = name;
this.isNew = isNew;
this.getName = function () {return (this.isNew ? "New " : "") + this.name; }
}
Теперь на любом "классе", который наследуется от Лица, вы должны обновить конструктор, чтобы следовать форме. Вы можете обойти это, сделав что-то вроде:
Customer = function () {
Person.apply(this, arguments);
}
Это вызовет "Человек" в рамках нового "Заказчика", что позволит вам не знать о конструкции Person.
Speed
http://jsperf.com/inherited-vs-assigned
В принципе, я пытаюсь доказать здесь, что если вы создаете эти объекты в массе, ваш лучший маршрут - создать их на прототипе. Создание их как:
Person = function (name) {
this.name = name;
this.getName = function () {return this.name}
}
очень медленный, потому что для каждого создания объекта он создает новую функцию - он не просто ищет цепочку прототипов для уже существующей. И наоборот, если у вас есть только несколько объектов, которые методы называются чрезвычайно часто, определение их локально помогает с потерей скорости, просматривая цепочку прототипов.
Общие свойства
Это всегда меня. Скажем, у вас есть что-то вроде следующего:
Person = function () {
this.jobs = {};
this.setJob = function (jobTitle, active) {this.jobs[jobTitle] = active; }
}
Employee = function () {}
Employee.prototype = new Person();
var bob = new Employee();
bob.setJob('janitor', true);
var jane = new Employee();
console.log(jane.jobs);
Угадайте, что? Джейн дворник! Без шуток! Вот почему. Поскольку вы не определили this.jobs как новый объект при создании экземпляра Employee, теперь он просто ищет цепочку прототипов, пока не найдет "задания" и не использует их как есть. Весело, правда?
Итак, это полезно, если вы хотите отслеживать экземпляры, но по большей части вы найдете его невероятно расстраивающим. Вы можете обойти это, выполнив следующие действия:
Employee = function () { Person.apply(this); }
Это заставляет "Person" создавать новый "this.jobs".
Частные переменные Поскольку в javascript нет ничего действительно "private", единственный способ получить частные переменные - создать их в конструкторе, а затем сделать все, что опирается на них, инициализировать в конструкторе.
Person = function () {
var jobs = {};
this.setJob = function (jobTitle, active) {jobs[jobTitle] = active; }
this.getJob = function (jobTitle) { return jobs[jobTitle]; }
}
Однако это также означает, что вы должны вызывать этот конструктор при каждом экземпляре унаследованного класса.
Предложение
http://ejohn.org/blog/simple-javascript-inheritance/
Это супер базовый класс. Это легко. Оно работает. И он сделает то, что вам нужно, чтобы сделать 90% времени, не имея дело со всем безумством, которое может предложить javascript:)