Декларирането на свойства на прототип изобщо не е анти шаблон. Когато гледам prototype
обект, си мисля, че "това има прототипният обект от този тип за данни и методи."
Други предупредиха да не се дава на свойства референтна стойност в прототипа, например: Foo.prototype.bar = [];
--- защото масивите и обектите са референтни типове. Референтният тип е неизменен, следователно всеки екземпляр на "клас" се отнася до един и същ масив или обект. Просто ги задайте на null
в прототипа, след което им дайте стойност в конструктора.
Винаги включвам всички свойства в прототипа поради една много ясна причина: да съобщавам на други програмисти кои свойства са публично достъпни и какви са техните стойности по подразбиране, без да се налага да преглеждат конструктор, за да го разберат.
Това става особено полезно, ако създавате споделена библиотека, която изисква документация.
Помислете за този пример:
/**
* class Point
*
* A simple X-Y coordinate class
*
* new Point(x, y)
* - x (Number): X coordinate
* - y (Number): Y coordinate
*
* Creates a new Point object
**/
function Point(x, y) {
/**
* Point#x -> Number
*
* The X or horizontal coordinate
**/
this.x = x;
/**
* Point#y -> Number
*
* The Y or vertical coordinate
**/
this.y = y;
}
Point.prototype = {
constructor: Point,
/**
* Point#isAbove(other) -> bool
* - other (Point): The point to compare this to
*
* Checks to see if this point is above another
**/
isAbove: function(other) {
return this.y > other.y;
}
};
(Формат на документацията: PDoc)
Самото четене на документацията тук е малко неудобно, защото информацията за свойствата x
и y
са вградени във функцията на конструктора. Сравнете това с "анти-модела" за включване на тези свойства в прототипа:
/**
* class Point
*
* A simple X-Y coordinate class
*
* new Point(x, y)
* - x (Number): X coordinate
* - y (Number): Y coordinate
*
* Creates a new Point object
**/
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
/**
* Point#x -> Number
*
* The X or horizontal coordinate
**/
x: 0,
/**
* Point#y -> Number
*
* The Y or vertical coordinate
**/
y: 0,
constructor: Point,
/**
* Point#isAbove(other) -> bool
* - other (Point): The point to compare this to
*
* Checks to see if this point is above another
**/
isAbove: function(other) {
return this.y > other.y;
}
};
Сега гледането на прототипа ви дава моментна снимка на действителния обект, която е много по-лесна за визуализиране в главата ви и по-лесна за автора да напише документацията. Функцията конструктор също не е претрупана с документация и се придържа към работата по вдъхване на живот на Point
обект.
Прототипът има всичко и е каноничният източник на информация за това какво има "прототипният" Point
обект за двата метода и данни.
Бих казал, че невключването на свойствата на данните в прототипа е антимоделът.
person
Greg Burghardt
schedule
28.10.2014