一つの式でクラスを定義できるようにfunctionオブジェクトにメソッドを生やしてみる。一応、Function.prototypeは汚さず、IE6でも動く感じにしてみた。うん、読みにくいですね。。
function Class(c) {
if (c == null) {
c = function(){};
}
c.extend = _extends;
c.mixin = _mixin;
c.statics = _static;
return c;
}
function _extends(uber) {
function f(){}
f.prototype = uber.prototype;
this.prototype = new f;
return this;
}
function _mixin() {
var i=0, len=arguments.length
, prop
, cur
, proto=this.prototype
;
for (; i<len; i++) {
cur = arguments[i];
for (prop in cur) {
proto[prop] = cur[prop];
}
}
return this;
}
function _static() {
var i=0, len=arguments.length
, prop
, cur
;
for (; i<len; i++) {
cur = arguments[i];
for (prop in cur) {
this[prop] = cur[prop];
}
}
return this;
}
使い方
/*
var クラス名 = Class(コンストラクタ関数)
.extend(親クラス)
.mixin(インスタンスメソッドをまとめたオブジェクト, [...複数指定可能...] )
.statics(クラスメソッドをまとめたオブジェクト, [...複数指定可能...] );
必要ない句は省略できる。
*/
var Bird = Class(function(name){this.name = name})
.mixin({
fly: function(){
console.log(this.name + "はぱたぱた飛ぶよ");
}
});
var b = new Bird('ぴよぴよ');
b.fly();
var Penguin = Class(function(name){
Bird.call(this,name)
}).extend(Bird)
.mixin({
fly: function(){
console.log(this.name + "は飛べないんだ…");
},
swim: function(){
console.log(this.name + "はすいすい泳ぐよ");
}
});
var p = new Penguin('ぺんぺん');
p.fly();
p.swim();