Search code examples
javascriptdom-events

JavaScript Class and Custom event handler proper syntax


I understand that there are many different views on the way JavaScript should be written, but I was wondering if the way I am writing it is fine. I don't want to go into the workforce writing code that nobody understands.

The basic premise of this code was to test custom event handlers for objects, was wondering if there is any glaring "YOU SHOULD NOT DO THIS" type thing?

    function EventClass() {
        var self = this;
        var events = {};
        var i = 0;
        self.fire = function(evt, args) {
            for (x in events[evt])
                events[evt][x].call(this, args);
        }

        self.on = function(evt, fn) {
            if (events[evt] == null) {
                events[evt] = []
            }
            events[evt].push(fn);
        }
    };

    function Human(x, y) {
        var self = this;
        self.__proto__ = new EventClass();
        var xCoord = 0;
        var yCoord = 0;

        self.events = {
            "MOVEMENT" : "movement"
        };

        self.init = function(x,y) {
            xCoord = x;
            yCoord = y;
        }

        self.draw = function(context) {
            context.beginPath();
            context.arc(xCoord,yCoord,10,0,Math.PI*2,true);
            context.closePath();
            context.fill();
        }

        self.moveLeft = function() {
            xCoord -= 5;
            self.fire(self.events.MOVEMENT, xCoord);
        }
        self.init(x,y);
    };

    function Player(x, y) {
        var self = this;
        self.__proto__ = new Human();
        self.init(x,y);
    };

    function Canvas(c) {
        var self = this;
        var canvas;
        var context;
        var objects = [];
        
        self.init = function(c) {
            canvas = c;
            context = canvas.getContext("2d");
        };

        this.redraw = function() {
            context.clearRect(0,0,300,300);
            for (x in objects) {
                objects[x].draw(context);
            }
        }

        this.addObject = function(obj) {
            objects.push(obj);
            obj.on(obj.events.MOVEMENT, function(coord) {
                console.log(coord);
                self.redraw();
            });
        };
        self.init(c);
    }


    var canvas = new Canvas(document.getElementById("canvas"));
    var human0 = new Human(75,75);
    canvas.addObject(human0);
    var human1 = new Human(100,100);
    canvas.addObject(human1);
    var player = new Player(200,200);
    canvas.addObject(player);

    canvas.redraw();

Solution

  • A couple of small things -- sort of.

    The first one is tiny.

    Be consistent with the this and self thing. The example I'm thinking of here is in your Canvas constructor.

    The truth of the matter is that nothing inside of your particular implementation requires self. Unless you're planning on giving your methods to other objects, or callbacks, self isn't required, there, until you get into writing functions which exist INSIDE of the methods. And even then, all self will help with is accessing the public properties/methods of that particular instance, and wouldn't help you access events or i or whatever.

    Not to say that it's not good to do -- it's just more-useful when you're doing the object-composition thing, rather than object-construction thing (and frequently becomes downright necessary, then).

    The second thing was more of a problem. __proto__ might be reasonably-well supported, if you're talking about FireFox/Chrome, but if you need to support wide swaths of browsers, you're going to make your life much more difficult by doing things that way, rather than adding to the ConstructorFN.prototype object.