Правильные конструкторы в javascript

Рейтинг: 4Ответов: 1Опубликовано: 12.10.2014

Здравствуйте. Есть какой-нибудь конструктор.

var Animal = function (data) {
  this.name = data.name;
  this.age = data.age;
  this.kind = data.kind;
}

Надо произвести валидацию входных данных. То есть убедится, что typeof name === String, typeof age === 'number' и 1+['cat', 'dog', 'mongoose'].indexOf(kind). Как это проверить очевидно. Вопрос в том, где проверять. Прямо в конструкторе? Или так:

var validate = function () {
  if (typeof this.name !== 'string') throw new Error;
  if (typeof this.age !== 'number') throw new Error;
  if (-1 === ['cat', 'dog', 'mongoose'].indexOf(kind)) throw new Error;
},
Animal = function (data) {
  this.name = data.name;
  this.age = data.age;
  this.kind = data.kind;
  validate.call(this);
}

Как это вообще делать правильно?

@eicto,

разница в моем и вашем коде ещё и такая - я сначала валидирую, а потом провожу инициализацию

Animal = function (data) {
    validate.call(this);
    this.name = data.name;
    this.age = data.age;
    this.kind = data.kind;
}

Тот факт, что валидация происходит в конструкторе уже считается признаком гавнокода?

@Etki,

Но если вы не стремитесь писать идеальный код сразу же - ну эээ это печально.

Ну с чего бы я вообще подымал бы этот вопрос, если бы не стремился писать нормальный код изначально))?

Ответы

▲ 1Принят

Чтобы писать валидирущий код сразу, не задумываясь, но следуя неким правилам, лучше использовать TypeScript или flow. По сути вашего вопроса: не так существенно, где проверять в первый раз, однако разумно делать функцию this.valid(), чтобы в любой момент узнать статус инстанса, а это бывает полезнее, чем бросать исключения. Но если задумка такова:

var Animal = function (data) {
  if(data === null || typeof data !== 'object') throw new Error;
  this.name = data.name;
  this.age = data.age;
  this.kind = data.kind;
  this.validate();
};

Animal.prototype.validate = function () {
  if (typeof this.name !== 'string') throw new Error;
  if (typeof this.age !== 'number') throw new Error;
  if (-1 === ['cat', 'dog', 'mongoose'].indexOf(kind)) throw new Error;
};