Inheritance in Javascript, What am I doing wrong here?

184 views Asked by At

Hi I am very new to javascript. i have been given the task to create a javascript framework to load multiple e-learning module and make them interact with each other via xml.

I am using a method of inheritance as shown below.

Base class EventDispatcher:

(function (window) {
    var EventDispatcher = function () {
            this._listeners = [];
        }
    var p = EventDispatcher.prototype;
    p._listeners = [];
    p.addListener = function (type, listener, scope) {
        scope = (typeof scope !== "undefined") ? scope : this;
        if (typeof this._listeners[type] == "undefined") {
            this._listeners[type] = [];
        }
        this._listeners[type].push({
            listener: listener,
            scope: scope
        });
    }
    p.removeListener = function (type, listener) {
        if (this._listeners[type] instanceof Array) {
            var listeners = this._listeners[type];
            for (var i = 0, len = listeners.length; i < len; i++) {
                if (listeners[i].listener === listener) {
                    listeners.splice(i, 1);
                    break;
                }
            }
        }
    }
    p.dispatchEvent = function (event) {
        if (typeof event == "string") {
            event = {
                type: event
            };
        }
        if (!event.target) {
            event.target = this;
        }
        if (!event.type) {
            throw new Error("Event object missing 'type' property.");
        }
        if (this._listeners[event.type] instanceof Array) {
            var listeners = this._listeners[event.type];
            for (var i = 0, len = listeners.length; i < len; i++) {
                listeners[i].listener.call(listeners[i].scope, event);
            }
        }
    }
    window.EventDispatcher = EventDispatcher;
}(window));

The Sub XMLLoader class that inherits EventDispatcher:

(function (window) {
    var XMLLoader = function () {}
    var p = XMLLoader.prototype = new EventDispatcher();
    p.xmlhttp = null;
    p.loadXML = function (url) {
        if (this.xmlhttp == null) {
            this.initXMLHttpRequest();
        }
        this.xmlhttp.open("GET", url, true);
        this.xmlhttp.send();
    }
    p.initXMLHttpRequest = function () {
        var currObj = this;
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            this.xmlhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        this.xmlhttp.onreadystatechange = function () {
            var xmlLoaderEvent = null;
            if (currObj.xmlhttp.readyState == 4 && currObj.xmlhttp.status == 200) {
                xmlLoaderEvent = new XMLLoaderEvents();
                xmlLoaderEvent.type = XMLLoaderEvents.XML_DOC_SUCCESS;
                xmlLoaderEvent.data = {
                    xmlDoc: currObj.xmlhttp.responseXML,
                    xmlString: currObj.xmlhttp.responseText
                };
            } else if (currObj.xmlhttp.status == 404) {
                xmlLoaderEvent = new XMLLoaderEvents();
                xmlLoaderEvent.type = XMLLoaderEvents.XML_DOC_ERROR;
            }
            if (xmlLoaderEvent != null) {
                currObj.dispatchEvent(xmlLoaderEvent);
            }
        };
    }
    /*p.onReadyStateChange = function()
    {
        var xmlLoaderEvent = null;
        if(this.xmlhttp.readyState == 4 && this.xmlhttp.status == 200)
        {
            xmlLoaderEvent = new XMLLoaderEvents();
            xmlLoaderEvent.type = XMLLoaderEvents.XML_DOC_SUCCESS;
            xmlLoaderEvent.data = this.xmlhttp.responseXML;
        }
        else if(this.xmlhttp.status == 404)
        {
            xmlLoaderEvent = new XMLLoaderEvents();
            xmlLoaderEvent.type = XMLLoaderEvents.XML_DOC_ERROR;
        }

        if (xmlLoaderEvent != null)
        {
            this.dispatchEvent(xmlLoaderEvent);
        }
    }*/
    window.XMLLoader = XMLLoader;
}(window));

Now I am calling the xmlLoader multiple times in another class. Before calling it everytime I create a new instance using new XMLLoader();. My understanding was that this should create a new instance and this._listeners in the base class should be [] empty. But that is not happening. Please help me and tell me where I am going wrong.

1

There are 1 answers

2
Samuel Rossille On BEST ANSWER

Class inheritance doesn't work as usual when simulated in javascript. For example, there is no implicit superclass constructor calling.

You don't call the "mother class" construtor in your "subclass constructor". That's why "Mother class" fields are not initialized.

Instead of

var XMLLoader = function () {}

what you should write is

var XMLLoader = function () {
    EventDispatcher.apply(this, arguments); /* this is a common way to execute
       the code of the "mother class" "constructor" with the same "this" */
}