jQuery and "this" management? How to avoid variable collisions?
<p>When you are writing complex jQuery/javascript, how do you manage using <code>this</code> without re-defining <code>this</code> variables that were previously defined? Do you have a rule of thumb or a personal preference for naming your <code>this</code> variables (as the nesting gets deeper)?</p>

<p>There are times where I want variables from a higher scope to be available to nested functions/callbacks, but then there are times when I'd like to have a clean slate/scope; is there a good way to call functions/callbacks without having to worry about variable collisions? If so, what technique(s) do you use?</p>

<hr>

<p>Some super silly test code:</p>

<pre><code>$(document).ready(function() {

    console.warn('start');

    var $this = $(this),

    $dog = $('#dog'),

    billy = function() {

        console.log('BILLY!', 'THIS:', $this, ' | ', 'DOG:', $dog);

        var $this = $(this);

        console.log('BILLY!', 'THIS:', $this, ' | ', 'DOG:', $dog);

    };

             // (#1)
    billy(); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
             // BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)

    console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(Document /demos/this/) | DOG: jQuery(p#dog)

             // (#2)
    billy(); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
             // BILLY! THIS:  jQuery(Window /demos/this/) | DOG: jQuery(p#dog)

    $('#foo').slideUp(function() {

                                                          // (#3)
        console.log('THIS:', $this, ' | ', 'DOG:', $dog); // BILLY! THIS: undefined | DOG: jQuery(p#dog)

        var $this = $(this); // (#10)

                                                          // (#4)
        console.log('THIS:', $this, ' | ', 'DOG:', $dog); // BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)

    });

    $('#clickme').click(function() {

                                                          // (#5)
        console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: undefined | DOG: jQuery(p#dog)

        var $this = $(this);

                                                          // (#6)
        console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(button#clickme) | DOG: jQuery(p#dog)

        $('#what').animate({
            opacity : 0.25,
            left    : '+=50',
            height  : 'toggle'
        }, 500, function() {

                                                              // (#7)
            console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: undefined | DOG: jQuery(p#dog)

            var $this = $(this);

                                                              // (#8)
            console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(div#what) | DOG: jQuery(p#dog)

        });

    });

             // (#9)
    billy(); // THIS: undefined | DOG: jQuery(p#dog)
             // THIS: jQuery(div#foo) | DOG: jQuery(p#dog)

    console.warn('finish');

});
</code></pre>

<p><a href="http://jsbin.com/oyegag/3">A full demo page can be found here (jsbin.com)</a>.</p>

<p><strong>Note:</strong> As you can see, I've "marked" the comments with numbers (#XX) for easy reference.</p>

<hr>

<h2>Observation 1:</h2>

<p><strong>Marker (#1)</strong></p>

<pre><code>BILLY! THIS: undefined | DOG: jQuery(p#dog)
</code></pre>

<p><strong>Rhetorical question:</strong> Why is <code>$this</code> undefined, but <code>$dog</code> is accessible?</p>

<p><strong>Answer:</strong> Because the <code>var</code> within that scope is re-defining <code>$this</code>; it's just that I'm trying to log <code>$this</code> before its been defined within that scope.</p>

<p>If I comment out <code>var $this = $(this);</code>, then the <strong>marker (#1)</strong> returns:</p>

<pre><code>BILLY! THIS: jQuery(Document index2.html) | DOG: jQuery(p#dog)
BILLY! THIS: jQuery(Document index2.html) | DOG: jQuery(p#dog)
</code></pre>

<p>The same logic applies to <strong>markers (#2), (#3), (#4), (#5), (#6), (#7) and (#8)</strong>.</p>

<p>Based on this observation (and please correct me if I'm wrong here) I'm assuming that I could put <code>var $this = $(this);</code> at the bottom of the function, and the current scope would know that I want to use the current scope's <code>$this</code> (even though it's not defined yet), and not the parent's <code>$this</code> (even though it <strong>IS</strong> defined).</p>

<h3>POSSIBLE SOLUTION TO AVOIDING <code>$this</code> CONFLICTS:</h3>

<p>If one wants to cache <code>$(this)</code> outside/within other closures/functions/callbacks and avoid collisions, then one should use different variable labels like these (for example):</p>

<pre><code>var $$ = $(this);
var $this2 = $(this);
var $t = $(this);
var $that = $(this);
</code></pre>

<h3>QUESTION:</h3>

<p>Is the solution above how you would avoid <code>$this</code> collisions? If not, what's your prefered technique?</p>

<hr>

<h2>Observation 2:</h2>

<p><strong>Marker (#9)</strong></p>

<pre><code>THIS: undefined | DOG: jQuery(p#dog)
</code></pre>

<p>... <code>$this</code> is undefined for reasons mentioned above, but:</p>

<pre><code>THIS: jQuery(div#foo) | DOG: jQuery(p#dog)
</code></pre>

<p>... <code>$this</code> is now <code>$('#foo')</code>!</p>

<h3>QUESTION(S):</h3>

<p>Exactly why did this happen?</p>

<p>Is it because <code>$this</code> was re-defined via <strong>marker (#10)</strong>?</p>

<p>(Hmmm, I feel like I need to Google "garbage collection in javascript".)</p>

<p>Again, when writing complex jquery/javascript, what's the best way to avoid this type of variable collision?</p>

<hr>

<p><em>I hope these aren't horrible questions. Thanks in advance for taking the time to help me out. :)</em></p>
