ちょっと検索したらダンコーガイの記事を見つけた。
このコードだと new Type(ほげほげ) のほげほげの部分のパラメータが、作られるオブジェクトのメンバーになると決まってしまっている(for (var p in o) this[p] = o[p];の部分)。
これをもうちょっと変えればコンストラクタもちゃんと動くのではないかと思う。
window.DeriveClass = function(baseClass, properties, methods, constructor) { var derivedClass = function() { if ((derivedClass.baseClass != undefined) && (derivedClass.baseClass != Object)) { derivedClass.baseClass.derive.apply(this, arguments); } for (var propertyName in properties) { this[propertyName] = properties[propertyName]; } if ((constructor !== undefined) && (constructor != null)) { constructor.apply(this, arguments); } }; if ((baseClass == undefined) || (baseClass == null)) { baseClass = Object; } derivedClass.prototype = new baseClass(); derivedClass.derive = derivedClass; derivedClass.baseClass = baseClass; for (var methodName in methods) { derivedClass.prototype[methodName] = methods[methodName]; } return derivedClass; }; // Following code is an example. var Mammal = DeriveClass ( Object, { name: "A mammal", gender: "Male", }, { eat: function(food) { alert(this.name + " ate " + food + "."); } }, function (name, gender) { var message = "This is the constructor of Mammal"; if (name != undefined) { message += " for " + name } if (name != undefined) { this.name = name; } if (gender != undefined) { this.gender = gender; } alert(message); } ); var DemiHuman = DeriveClass ( Mammal, null, { eat: function(food) { var name = (this.gender == "Male") ? "Mr." : "Mz."; name += this.name; alert(name + " cooked and ate " + food + "."); } }, function (name, gender) { var message = "This is the constructor of DemiHuman"; if (name != undefined) { message += " for " + name } //if (name != undefined) { this.name = name; } //if (gender != undefined) { this.gender = gender; } alert(message); } ); var Human = DeriveClass ( DemiHuman, null, null, function (name, gender) { var message = "This is the constructor of Human"; if (name != undefined) { message += " for " + name } //if (name != undefined) { this.name = name; } //if (gender != undefined) { this.gender = gender; } alert(message); } ); var john = new Human("John", "Male"); john.eat("a magical cookie");
こんな感じで、とりあえず簡単なサンプルが Firefox では動いた。
DeriveClass(元クラス, プロパティ, メソッド, コンストラクタ)みたいに書ける。
ちゃんと親のほうのクラスからコンストラクタが順番に呼ばれる。