JavaScript: OOP in JS mit Namespace und simple inheritance

So, und in diesem Snippet geht es noch einen Schritt weiter. Der Unterschied zum letzten JS Post ist die Verwendung der Simple inheritance von John Resig.

Diese vereinfacht die Schreibweise und macht den Code übersichtlicher und strukturierter. Auch die Verwendung von prototype entfällt komplett.

In der Quintus HTML5 game engine wurde dieses Konzept noch ein klein wenig weiter getrieben, diesem werde ich aber hoffentlich bald auf die Schliche kommen, da ich dieses im Moment noch nicht ganz verstehe ;-)

/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function(){
    var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
    // The base Class implementation (does nothing)
    this.Class = function(){};

    // Create a new Class that inherits from this class
    Class.extend = function(prop) {
        var _super = this.prototype;

        // Instantiate a base class (but only create the instance,
        // don't run the init constructor)
        initializing = true;
        var prototype = new this();
        initializing = false;

        // Copy the properties over onto the new prototype
        for (var name in prop) {
            // Check if we're overwriting an existing function
            prototype[name] = typeof prop[name] == "function" &&
                typeof _super[name] == "function" && fnTest.test(prop[name]) ?
                (function(name, fn){
                return function() {
                    var tmp = this._super;

                    // Add a new ._super() method that is the same method
                    // but on the super-class
                    this._super = _super[name];

                    // The method only need to be bound temporarily, so we
                    // remove it when we're done executing
                    var ret = fn.apply(this, arguments);
                    this._super = tmp;

                    return ret;
                };
            })(name, prop[name]) :
                prop[name];
        }

        // The dummy class constructor
        function Class() {
            // All construction is actually done in the init method
            if ( !initializing && this.init )
                this.init.apply(this, arguments);
        }

        // Populate our constructed prototype object
        Class.prototype = prototype;

        // Enforce the constructor to be what we expect
        Class.prototype.constructor = Class;

        // And make this class extendable
        Class.extend = arguments.callee;

        return Class;
    };
})();

//Namespace
var TEST = TEST || { version: 1 }

//Object 1
TEST.MyObject = Class.extend({
    init: function(val){
        this.property1 = val
    },
    method1: function(){
        console.log('method1 parent called')
    }
})

//Object 2
TEST.MyObject2 = TEST.MyObject.extend({
    init: function(val){
        this._super(val) //call super class constructor
        this.property2 = 2
    },
    method1: function(){
        this._super() //call parent method1
        console.log('method1 child called')
    }
})

JavaScript: OOP in JS mit Namespace

Im letzten JavaScript Post habe ich die Objektorientierung gestreift. Doch wie werden Objekte in einem Namespace bzw. einem über Objekt zusammengefasst?

Folgender kleiner Snippet soll dieses veranschaulichen. In diesem werden zwei Klassen zusammen gefasst. Auch hier wird wieder gezeigt wie man den Konstruktor oder Methoden der Elternklasse aufruft.

//Namespace
var TEST = TEST || { version: 1 }

//Object 1
TEST.MyObject = function (){
    this.property1 = 1
    console.log('obj1')
    return this
}
//leider kann hier der constructor nicht richtig gesetzt werden
//in der Konsole erscheint beim log immer object als Konstruktorname ;o(
//TEST.MyObject.prototype.constructor = TEST.MyObject
TEST.MyObject.prototype.method1 = function () {
    console.log('method1 called')
    return 'method1'
}

//Object2
TEST.MyObject2 = function(){
    TEST.MyObject.call(this) //call super class constructor
    this.property2 = 2
    console.log('obj2')
    return this
}
//inherit from prototype
TEST.MyObject2.prototype = Object.create(TEST.MyObject.prototype)
//TEST.MyObject2.prototype.constructor = TEST.MyObject2
TEST.MyObject2.prototype.method2 = function(){
    TEST.MyObject.prototype.method1.call(this)
    console.log('method2 called')
}