Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find the instance to which a method belongs?

Tags:

javascript

// minified base class code (if the uncompressed code is needed, I'll post it) function Class(){}Class.prototype.construct=function(){};Class.extend=function(c){var a=function(){arguments[0]!==Class&&this.construct.apply(this,arguments)},d=new this(Class),f=this.prototype;for(var e in c){var b=c[e];if(b instanceof Function)b.$=f;d[e]=b}a.prototype=d;a.extend=this.extend;return a};

// custom event class
var Event = Class.extend({
    handlers: [],
    // stores the event handler
    subscribe: function(handler, thisObj) {
        this.handlers.push([handler, thisObj]);
    },
    // calls the event handlers
    fire: function() {
        for(i in this.handlers) {
            var handler = this.handlers[i];
            handler[0].apply(handler[1]);
        }
    }
});
var Class2 = Class.extend({
    myEvent: new Event(), // the event
    test: function() { // fires the event
        this.myEvent.fire(this);
    }
});
var Class3 = Class.extend({
    construct: function(model) {
        this.name = "abc";
        model.myEvent.subscribe(this.handler, this); // subscribe to the event
    },
    handler: function() {
        alert(this.name); // alerts 'abc'
    }
});
var instance1 = new Class2();
var instance2 = new Class3(instance1);
instance1.test();

The only way to make the event handler code to work with the good 'this' is by adding a new argument ('thisObj') to the 'subscribe' method? Is there a better way to do this?

like image 844
silviubogan Avatar asked Nov 05 '22 11:11

silviubogan


1 Answers

The behaviour you're getting is due to the fact that when you pass a "method" to a function, the receiving function has no idea it's a method. It's just a block of javascript that needs to get executed.

Prototype gets around this issue with the bind method

  • http://api.prototypejs.org/language/function/prototype/bind/

You can get similar behaviour (I didn't look at the implementation details of bind) by using a closure.

var Class3 = Class.extend({
    construct: function(model) {
        this.name = "abc";
        //model.myEvent.subscribe(this.handler, this); // subscribe to the event
        var self = this;
        model.myEvent.subscribe(function() {self.handler()});
    },
    handler: function() {
        alert(this.name); // alerts 'abc'
    }
});

Or apply some similar functionality to the subscribe method of your custom event class.

EDITED To reflect CMS's observations. Thanks!

like image 190
Jamie Wong Avatar answered Nov 15 '22 04:11

Jamie Wong