2

Sorry if this has been answered, but I couldn't turn up a search for it... a difficult thing to search for, I think!

Say I have this:

var MyPrototype = function() { this.init(); }
$.extend(MyPrototype.prototype, {
    a: 5,
    init: function() {
        var thing = new SomeOtherClass();
        thing.meth = this.meth;
        // thing.meth() is called somewhere within thing;
    },
    meth: function() {
        alert(this.a);
    }
}

Basically, I am dealing with another class which uses its own methods as callbacks, e.g. I am expected to override them with my own functionality. But I need to retain the proper scope of this while doing it (the only thing I care about from SomeOtherClass is what's passed to the callback; nothing in the state).

As you might imagine, this doesn't work because thing has no a property! I am not familiar enough with the intricacies of Javascript scoping to know how to make this refer to what I want, though!

tdavis
  • 1,422
  • 2
  • 13
  • 12
  • Please see: http://stackoverflow.com/questions/520019/controlling-the-value-of-this-in-a-jquery-event ...and also: http://stackoverflow.com/questions/1043556/how-can-i-keep-the-context-of-this-in-jquery ...and really, most of the questions in: http://stackoverflow.com/questions/tagged/this+javascript (this is an extremely common point of confusion) – Shog9 Jul 27 '09 at 22:44

5 Answers5

2

Combining two other answers here, so that you don't have to rewrite your meth function, I'd do this:

    var me = this;
    thing.meth = function() {
        MyPrototype.meth.apply(me, arguments);
    };
edsoverflow
  • 591
  • 3
  • 3
1

Since you can't control how it's called you could try this:

var MyPrototype = function() { this.init(); }
$.extend(MyPrototype.prototype, {
    a: 5,
    init: function() {
        var thing = new SomeOtherClass();

        // Create an aliad for this
        var that = this;
        thing.meth = function() {
            // You can always access the object using it's "that" alias
            alert(that.a);
        };
    }
}

Or...

var MyPrototype = function() { this.init(); }
$.extend(MyPrototype.prototype, {
    a: 5,
    init: function() {
        var thing = new SomeOtherClass();

        // Create an aliad for this
        var that = this;
        thing.meth = function() {
            // You can always access the object using it's "that" alias
            that.meth();
        };
    },
    meth: {
        alert(this.a);
    }
}
Chris Pietschmann
  • 29,502
  • 35
  • 121
  • 166
0

Before the start of your code sample, add this line:

var self = this;

Then replace all uses of 'this' in your code with 'self'.

(I think a bunch of the answers to this are saying more or less the same thing.)

aem
  • 3,896
  • 24
  • 20
-1

How about:

thing.meth.call(this);

or

thing.meth.apply(this);

(The only difference is in how arguments are passed, which doesn't matter in this case.)

Tim Sylvester
  • 22,897
  • 2
  • 80
  • 94
  • Unfortunately, as they are callbacks initiated from `SomeOtherClass`, I don't actually control how they are called. – tdavis Jul 27 '09 at 21:46
  • In that case, you just need to wrap the callback in a closure so the value of "this" is carried along with the function reference. *edsoverflow* already posted an example. – Tim Sylvester Jul 27 '09 at 22:23
-1

Could you do something like this?

var MyPrototype = function() { this.init(); }
$.extend(MyPrototype.prototype, {
    a: 5,
    init: function() {
        var thing = new SomeOtherClass();
        var self = this;
        thing.meth = function(){this.meth.apply(self)};
        // thing.meth() is called somewhere within thing;
    },
    meth: function() {
        alert(this.a);
    }
}
agilefall
  • 3,876
  • 3
  • 31
  • 27