JavaScriptにおけるクラスと継承の書き方

(注:この記事は思考の整理程度で不完全です)
一番簡単に書くとこう。prototypeを他のクラスからコピーすることで継承もできる

// class Color
function Color() {
    this.init.apply(this, arguments);
    return this;
}

Color.prototype.init = function() {
    ...
};

...

ふつうJavaScriptで継承まですることは少ないのでprototypeをまるまる書き換えることもできる。

Color.prototype = {
    init: function() { ... },
    ...
};

でもやっぱり継承したくなって Object.extend という関数を作る。

Object.extend = function(destination, source) {
    for (var property in source) {
        destination[property] = source[property];
    }
};

Object.extend(Color, {
    init: function() { ... },
    ...
});

別な角度から、staticな変数もほしくなってこう書く。

(function() {
    var C = Color; // class
    var P = C.prototype; // class.prototype

    var privateStaticVariable;
    C.publicStaticVariable;
    
    P.init = function() { ... };
    ...
})();

そのうちCとかPとか書くのが汚いと思いだしてこうなる。前の Object.extend みたいにオブジェクトを渡すこともできる。ついでにクラスをクラス化する。

Function.prototype.extend = function(source) {
    if (typeof source === "function") {
        source(this, this.prototype);
    }
    else if (typeof source === "object") {
        for (var prop in source) {
            this[prop] = source[prop];
        }
    }
};

function Class() {
    var newClass = function() {
        var value = (this.init) ? this.init.apply(this, arguments) : this;
        return value;
    };
    
    newClass.constructor = Class;
    newClass.prototype.constructor = newClass;
    
    if (arguments[0]) {
        newClass.extend(arguments[0]);
    }
    
    return newClass;
}

// class Color
var Color = new Class(function(C, P) {
    P.init = function() { ... };
    ...
});

とりあえずこんなところで!(まだ完全じゃない)