Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have seen this pattern in several answers from some of the brightest minds on this site so I know there is a reason.

For the life of me though I do not seem to understand why this would need to be done:

Lightning Components in Visualforce - Unable to read sobject

var self=this;
action.setCallback(this, function(response) {
        self.actionResponseHandler(response, cmp, self, self.sentAccount);
});

What is the purpose of self instead of just using this

share|improve this question
up vote 5 down vote accepted

In JavaScript, when you refer to a variable outside of the current function, you create a closure. Basically, you are guaranteeing that you will have access to a given variable, which in this case, happens to be the object that contains the method. As noted in the other answer, "this" is notoriously hard to pin down, a side effect of how JavaScript determines its scope.

However, notice how the framework inherently protects you from this behavior; the author of that code didn't need to specify "self", because setCallback actually sets "this" to the first parameter, which is typically "this." In plain JavaScript, you end up needing to use this trick all the time, because its the only way to guarantee that you'll know which object you're referring to.

The only time you need to use "self" in Lightning is when you start creating objects in code. For example, you might create some sort of helper object:

({
    increment: function() {
        // this refers to the helper object
        // but self refers to the object created in getHelper
        // this.counter++ would crash; this.counter is undefined
        self.counter++; // Increments the helper's counter
    },
    getHelper: function() {
        return (function() {
            var self = this;
            self.counter = 0;
            return {
                increment: increment                    
            };
        })();
    }
})

I apologize for the complexity of this code, but hopefully it demonstrates when you'd want to use self instead of this.

share|improve this answer
1  
At what point in the code snippet would you actually be able to reference self? – Adrian Larson 7 hours ago
1  
Thanks sfdcfox that makes perfect sense to me. I hate switching answers but for me this fits my thought process much better (I am a strange bird). Adrian I appreciate your answer very much as well. Thank you both....I assume that you could then reference self in the doSomething method? Maybe an example of that nuance? – Eric 7 hours ago
    
@AdrianLarson You'd use "self" in the doSomething and doSomethingElse methods. As the "comment" states, this refers to the compoenentNameHelper.js file, while self would refer to the object returned from getHelper. – sfdcfox 7 hours ago
1  
That's...mind bending. It doesn't seem like it should be in scope. – Adrian Larson 7 hours ago
1  
@sfdcfox - Hope u do not mind I put the two comments back because for me at least they provided the context I needed – Eric 7 hours ago

I suggest you read up on the documentation for this on MDN.

A function's this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.

In most cases, the value of this is determined by how a function is called. It can't be set by assignment during execution, and it may be different each time the function is called. ES5 introduced the bind method to set the value of a function's this regardless of how it's called, and ES6 introduced arrow functions whose this is lexically scoped (it is set to the this value of the enclosing execution context).

In other words, it's complicated. It depends on context, and even which version of Javascript is running!


Context can change what is held in the this variable. For example, inside of your anonymous callback function, it isn't immediately clear whether this refers to what it did on the line before, or if it refers to action, or response, or something else. Basically, you make your callback less context dependent.

Consider this page:

<apex:page>
    <button>Click Me!</button>
    <script>
        (function (D, w) {
            "use strict";
            var N = w.myNamespace = w.myNamespace || {}
            N.doStuff = function () {
                var self = this;
                [].forEach.call(D.getElementsByTagName("button"), function (element) {
                    console.debug(self);
                    console.debug(this);
                    element.addEventListener("click", function (event) {
                        console.debug(self);
                        console.debug(this);
                    });
                });
            }
            D.addEventListener("DOMContentLoaded", N.doStuff);
        }(document, window));
    </script>
</apex:page>

The onload debugs will yield:

#document
undefined

However, if you then call myNamespace.doStuff from the console, you will get:

Object { }
undefined

And if you click the button, you will get:

#document
<button>Click Me!</button>

Be wary of using this if you aren't sure what it is in a given context. Even if you alias it to self, the context in which you do so has the same issue.

share|improve this answer
    
I added link to where I got the code from. I know I saw some answers from sfdcfox as well using this pattern. I have not had to use it so having a hard time wrapping my head around it. To me this is being passed in so should it not be the same as self which was previously set to this anyways? – Eric 9 hours ago
1  
Not inside the function. Working on a simpler example. – Adrian Larson 9 hours ago
1  
@Eric Not sure how much my answer helps...MDN is your best bet for understanding how this works though. – Adrian Larson 9 hours ago
1  
Chapter 4 (functions) in JavaScript: The Good Parts does a great job of describing the behavior of how this is assigned when functions are invoked and why the workaround exists to assign the context to a variable declared in the scope of the outer function which is then used by inner functions later. – Mark Pond 9 hours ago
    
@MarkPond Sounds like you might have a valuable answer to contribute! :) Good to see you around again. – Adrian Larson 9 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.