2

Lately a lot of my code has been looking like this...

function MyObjectClass (selector) {
    this.color  = "red";
    this.$elt   = $(selector);
    // ... any other object vars here ...

    // Example method for the object
    this.showThenUpdateColor = function () { 
        // Keep a copy of "this" to use for callbacks
        var o = this;
        // Example of jQuery function that accepts a callback           
        o.$elt.fadeIn(function(){ 
            // Inside of this callback function we need to access the main object
            o.$elt.css({
                "background-color" : o.color // This is where we need the "o"
            });
        });
    }
}
var myObject = new MyObjectClass('#myObject');
myObject.showThenUpdateColor();

...where I have a callback inside of an object method. Typically I assign the object itself ("this") to a local variable (usually "o" because it's short and easy) which can be used in the callback.

Is this an optimal use of memory? Is there any danger of memory leaks? Is there a better way?

Luke
  • 18,811
  • 16
  • 99
  • 115
  • 1
    I just add this link[1] to the discussion, it's interesting. The answers (not only the accepted one) give a good explanation of how to handle "this". Anyway your question is different: "Is this an optimal use of memory?". This is why I'm providing this in a comment, and I will follow the discussion. [1] http://stackoverflow.com/questions/10766407/javascript-callbacks-losing-this – Lorenzo S Feb 27 '14 at 18:33
  • 1
    Yes, no, and no - there are only *other* ways. See [How to access the correct \`this\` / context inside a callback?](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – Bergi Feb 27 '14 at 19:00
  • Thanks Bergi, that's the basic answer I was looking for. Although the ideal answer would include some explanation of how we know it is the optimal use of memory. When I set `var o = this;` that just creates a reference to the object which i assume is very small in memory? Also not sure if the closure has some memory implications? – Luke Feb 27 '14 at 21:47

1 Answers1

3

I would recommend having a look at jQuery.proxy(). It lets you create a function that, when executed, executes another function in the scope you specify. You could then write:

this.showThenUpdateColor = function () { 
    // Example of jQuery function that accepts a callback           
    this.$elt.fadeIn($.proxy(this._onFadeInComplete, this));
}

function _onFadeInComplete() {
    this.$elt.css({
        "background-color" : this.color
    });
}
Strille
  • 5,741
  • 2
  • 26
  • 40
  • The nice thing about using `function _onFadeInComplete` instead of `this._onFadeInComplete = function()...` is that it's private to `MyObjectClass`, i.e. nothing can call it from outside of the class. – Strille Feb 27 '14 at 18:57