これは、 Akshellプラットフォーム用に作成したフレームワークの一部です。ここに完全なソリューションコードとドキュメントがあります 。 ただし、サーバー側のJavaScript環境では役立ちますが、サーバー側では、クラス階層の便利な作成が特に重要です。
__proto__
プロパティ
__proto__
使用して作業を
new
演算子で置き換える場合にも、クライアントで使用できます。
実際、ソリューション全体は
Function
クラスの
subclass
メソッドにあります。 環境で許可されている場合は、列挙不可にする必要があります。
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;
};
この関数は、コンストラクターと作成されるクラスのプロトタイプという2つのオプション引数を取ります。 引数を渡すセマンティクスは非標準ですが、この場合は便利です。最初の引数が関数の場合はコンストラクター、それ以外の場合はプロトタイプです。
クラス階層のおもちゃの例:
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
クラスのオブジェクトであるため、当然、
Function
サブクラスはクラスクラスまたはメタクラスです。 それらを定義することにより、クラスのインスタンス化を制御し、サブクラスに継承されたクラスの静的プロパティとメソッドを決定できます(サブクラスは、
subclass
メソッドの最後から2番目の行で親からメタクラスを受け取ります)。
たとえば、
Figure
サブクラスを演算子なしでインスタンス化し、各サブクラスに
optionalNew
プロパティが
true
設定されるようにし
true
。 これを行うには、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
すべてのサブクラスは、必要な変更を受け取ります。
もちろん、メタクラスはあまり広く使用すべきではありません。特に、
FigureMeta
は完全に
FigureMeta
な例です。 ただし、場合によっては、コードをはるかに短く理解しやすくすることができます。 たとえば、JavaScriptのDjangoフォームポートであるAkshellのjs-formsライブラリを適応させる場合、メタクラスを使用すると、Djangoと同じ宣言的な方法でフォームのサブクラスを作成できます(これにもPythonのみが使用されます)。 コードはわずか30行です。