__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