JavaScript - это прототипный язык, и все же он способен имитировать некоторые функции объектно-ориентированных языков на основе классов. Например, JavaScript не имеет понятия публичных и частных членов, но благодаря магии закрытия, все же можно обеспечить такую же функциональность. Точно так же могут быть добавлены так или иначе методы перегрузки методов, интерфейсы, пространства имен и абстрактные классы.
В последнее время, поскольку я программировал в JavaScript, я чувствовал, что я пытаюсь превратить его в классный язык вместо того, чтобы использовать его так, как он должен был использоваться. Кажется, я пытаюсь заставить язык соответствовать тому, к чему я привык.
Ниже приведен код JavaScript, который я написал недавно. Цель состоит в том, чтобы отвлечь часть усилий, связанных с рисованием элемента холста HTML5.
/*
Defines the Drawing namespace.
*/
var Drawing = {};
/*
Abstract base which represents an element to be drawn on the screen.
@param The graphical context in which this Node is drawn.
@param position The position of the center of this Node.
*/
Drawing.Node = function(context, position) {
return {
/*
The method which performs the actual drawing code for this Node. This method must be overridden in any subclasses of Node.
*/
draw: function() {
throw Exception.MethodNotOverridden;
},
/*
Returns the graphical context for this Node.
@return The graphical context for this Node.
*/
getContext: function() {
return context;
},
/*
Returns the position of this Node.
@return The position of this Node.
*/
getPosition: function() {
return position;
},
/*
Sets the position of this Node.
@param thePosition The position of this Node.
*/
setPosition: function(thePosition) {
position = thePosition;
}
};
}
/*
Define the shape namespace.
*/
var Shape = {};
/*
A circle shape implementation of Drawing.Node.
@param context The graphical context in which this Circle is drawn.
@param position The center of this Circle.
@param radius The radius of this circle.
@praram color The color of this circle.
*/
Shape.Circle = function(context, position, radius, color) {
//check the parameters
if (radius < 0)
throw Exception.InvalidArgument;
var node = Drawing.Node(context, position);
//overload the node drawing method
node.draw = function() {
var context = this.getContext();
var position = this.getPosition();
context.fillStyle = color;
context.beginPath();
context.arc(position.x, position.y, radius, 0, Math.PI*2, true);
context.closePath();
context.fill();
}
/*
Returns the radius of this Circle.
@return The radius of this Circle.
*/
node.getRadius = function() {
return radius;
};
/*
Sets the radius of this Circle.
@param theRadius The new radius of this circle.
*/
node.setRadius = function(theRadius) {
radius = theRadius;
};
/*
Returns the color of this Circle.
@return The color of this Circle.
*/
node.getColor = function() {
return color;
};
/*
Sets the color of this Circle.
@param theColor The new color of this Circle.
*/
node.setColor = function(theColor) {
color = theColor;
};
//return the node
return node;
};
Код работает точно так же, как и для пользователя Shape.Circle, но похоже, что он удерживается вместе с канальной лентой. Может ли кто-нибудь объяснить это?