silviubogan
silviubogan

Reputation: 3461

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

// 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?

Upvotes: 5

Views: 218

Answers (1)

Jamie Wong
Jamie Wong

Reputation: 18350

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

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!

Upvotes: 2

Related Questions