__proto__
property __proto__
the new
operator. subclass
method of the Function
class. If the environment allows, it is worth making it non enumerable.Function.prototype.subclass = function ( /* [constructor] [, prototype] */ ) {
var self = this ;
var constructor = (
typeof (arguments[0]) == 'function'
? Array.prototype.shift.call(arguments)
: ( this === Object
? function () {}
: function () { self.apply( this , arguments); }));
if (arguments[0])
constructor.prototype = arguments[0];
constructor.prototype.__proto__ = this .prototype;
constructor.__proto__ = this .__proto__;
return constructor;
};
var Figure = Object.subclass(
{
getArea: function () {
throw Error( 'Abstract' );
}
});
var Rectangle = Figure.subclass(
function (a, b) {
this .a = a;
this .b = b;
},
{
getArea: function () {
return this .a * this .b;
}
});
var Square = Rectangle.subclass(
function (a) {
Rectangle.call( this , a, a);
});
Function
class, then naturally subclasses of Function
are classes of classes, or metaclasses. By defining them, you can control the instantiation of classes, as well as determine the static properties and methods of classes that are inherited by subclasses (the subclass receives the metaclass from its parent in the penultimate line of the subclass
method).Figure
subclasses to be instantiated without an operator and each of them has the optionalNew
property equal to true
. For this you need to write a metaclass for Figure:var FigureMeta = Function.subclass(
{
subclass: function () {
var constructor = Function.prototype.subclass.apply( this , arguments);
var result = function () {
var self = (
this instanceof arguments.callee
? this
: {__proto__: arguments.callee.prototype});
constructor.apply(self, arguments);
return self;
};
result.prototype = constructor.prototype;
result.__proto__ = this .__proto__;
return result;
},
optionalNew: true
});
Figure.__proto__ = FigureMeta.prototype;
Figure
subclasses defined after installing the metaclass will receive the necessary changes.FigureMeta
is a completely contrived example. However, in some cases they can make the code much shorter and clearer. For example, when adapting the js-forms library in Akshell, the Django forms port in JavaScript, metaclasses allowed to create subclasses of forms as declaratively as in Django (there are also metaclasses used for this, only the Python ones). The code takes only 30 lines .Source: https://habr.com/ru/post/94070/
All Articles