библиотека закрытия реализует классы со свойствами, определенными в прототипе, а также в функции-конструкторе. Помимо изучения исходного кода библиотеки Closure, вот несколько вопросов, которые следует учитывать при принятии решения о том, следует ли определять свойство в прототипе или в конструкторе.
Является ли свойство уникальным для каждого экземпляра класса?
Свойства, уникальные для каждого экземпляра (например, VIN-номер автомобиля), не должны использоваться совместно между экземплярами и поэтому определяются в конструкторе, а не в прототипе.
/**
* A car.
* @param {string} vin The Vehicle Identification Number.
* @constructor
*/
Car = function(vin) {
/**
* The Vehicle Identification Number.
* @type {string}
* @private
*/
this.vin_ = vin;
};
Является ли тип свойства неизменным (например, строка, логическое значение, число) или изменяемым (например, объект, массив)?
Поскольку неизменяемые типы свойств можно безопасно использовать между экземплярами, они должны быть определены в прототипе. Если экземпляру необходимо переопределить общее значение по умолчанию, может быть добавлено свойство экземпляра, которое затеняет свойство прототипа с тем же именем.
/**
* The number of cylinders in the engine.
* @type {number}
* @private
*/
Car.prototype.cylinders_ = 4;
/**
* Sets the number of cylinders in the engine.
* @param {number} cylinders The number of cylinders.
*/
Car.prototype.setCylinders = function(cylinders) {
if (this.cylinders_ == cylinders) {
// Since the number of cylinders has not changed, do not add a new
// instance property to shadow the prototype property. Instead, continue
// to use the prototype property.
return;
}
// Defines cylinders_ property on the instance object that shadows
// Car.prototype.cylinders_
this.cylinders_ = cylinders;
};
/**
* Gets the number of cylinders in the engine.
* @return {number} The number of cylinders.
*/
Car.prototype.getCylinders = function() {
return this.cylinders_;
};
В следующем примере показано, как установка свойства экземпляра затеняет свойство прототипа.
var myCar = new Car("1HGCM82633A004352");
alert(myCar.getCylinders()); // Alerts 4.
myCar.setCylinders(6);
alert(myCar.getCylinders()); // Alerts 6;
// Delete the instance property and let the prototype property
// "shine through".
delete myCar.cylinders_;
alert(myCar.getCylinders()); // Alerts 4;
Если тип свойства является изменяемым, например Array или Object, то в большинстве случаев вы не захотите использовать один и тот же экземпляр изменяемого свойства между экземплярами класса. Следовательно, изменяемые свойства чаще определяются в конструкторе, а не в прототипе.
Можно ли инициализировать свойства null
?
В библиотеке замыканий есть много примеров, где свойства инициализируются значением null.
. Однако лучше по возможности инициализировать переменные полезными значениями по умолчанию, например установить количество цилиндров по умолчанию равным 4, как в приведенном выше примере.
person
Christopher Peisert
schedule
31.08.2012