/** * CreateClass使用例 var Point2D = CreateClass(null, { initialize: function($super, x, y) { this.x = x; this.y = y; }, show: function() { alert([this.x, this.y]); } }); var Point3D = CreateClass(Point2D, { initialize: function($super, x, y, z) { $super(x, y); this.z = z; }, show: function() { alert([this.x, this.y, this.z]); }, show2D: function() { this.$super('show')(); } }); var pos = new Point3D(1, 2, 3); pos.show(); pos.show2D(); */ /** * クラスを作成する * * @param class superClass * @param hash prototype */ function CreateClass(superClass, prototype) { // オブジェクトの拡張 var extend = function(dst, src) { for(var key in src) dst[key] = src[key]; return dst; }; // 親クラスから必要なものを抽出する var extractSuper = function(obj) { var out = {}; for(var key in obj) if(typeof(obj[key]) == 'function' || key == '$_super') out[key] = obj[key]; return out; }; // initializeを再帰的に呼び出す関数を作成する var superInitializer = function(_this, $_super) { if($_super) { return function() { var args = Array.prototype.slice.apply(arguments); args.unshift(superInitializer(_this, $_super.$_super)); $_super.initialize.apply(_this, args); }; } return null; }; // コンストラクタ var klass = function() { var args = Array.prototype.slice.apply(arguments); args.unshift(superInitializer(this, this.$_super)); this.initialize.apply(this, args); }; // 継承・特殊メソッド定義 extend(klass.prototype, superClass ? superClass.prototype : {}); extend(klass.prototype, prototype); extend(klass.prototype, { $_super: superClass ? extractSuper(superClass.prototype) : null, $super: function(name, depth) { if(depth === undefined) depth = 1; var curr = this; for(var i=0; i<depth; i++) { curr = curr.$_super; if(!curr) throw 'Super class not found.'; } return curr[name].bind(this); } }); return klass; }
コメント