Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There are three main ways to deal with <code>this</code> in callbacks:</p> <h2>1. Create a lexically-scoped variable, as you are currently doing</h2> <p>The two most common names for this new variable are <code>that</code> and <code>self</code>. I personally prefer using <code>that</code> because browsers have a global window property called self and my linter complains if I shadow it.</p> <pre><code>function edit(req, res) { var that = this, db.User.findById('ABCD', function(err, user){ that.foo(user); }); }; </code></pre> <p>One advantage of this approach is that once the code is converted to using <code>that</code> you can add as many inner callbacks as you want and they will all seamlessly work due to lexical scoping. Another advantage is that its very simple and will work even on ancient browsers.</p> <h2>2. Use the .bind() method.</h2> <p>Javascript functions have a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind"><code>.bind()</code></a> method that lets you create a version of them that has a fixed <code>this</code>.</p> <pre><code>function edit(req, res) { db.User.findById('ABCD', (function(err, user){ this.foo(user); }).bind(this)); }; </code></pre> <p>When it comes to handling <code>this</code>, the bind method is specially useful for one-of callbacks where having to add a wrapper function would be more verbose:</p> <pre><code>setTimeout(this.someMethod.bind(this), 500); var that = this; setTimeout(function(){ that.doSomething() }, 500); </code></pre> <p>The main disadvantage of <code>bind</code> is that if you have nested callbacks then you also need to call <code>bind</code> on them. Additionally, <a href="http://kangax.github.io/compat-table/es5/#Function.prototype.bind">IE &lt;= 8 and some other old browsers</a>, don't natively implement the <code>bind</code> method so you might need to use some sort of <a href="https://github.com/es-shims/es5-shim">shimming library</a> if you still have to support them.</p> <h2>3. If you need more fine-grained control of function scope or arguments, fall back to .call() and .apply()</h2> <p>The more primitive ways to control function parameters in Javascript, including the <code>this</code>, are the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call"><code>.call()</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply"><code>.apply()</code></a> methods. They let you call a function with whatever object as their <code>this</code> and whatever values as its parameters. <code>apply</code> is specially useful for implementing variadic functions, since it receives the argument list as an array.</p> <p>For example, here is a version of bind that receives the method to bind as a string. This lets us write down the <code>this</code> only once instead of twice.</p> <pre><code>function myBind(obj, funcname){ return function(/**/){ return obj[funcname].apply(obj, arguments); }; } setTimeout(myBind(this, 'someMethod'), 500); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload