Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the rationale behind the "var self = this" approach? [duplicate]

Tags:

javascript

Possible Duplicate:
JS: var self = this?

When looking at arbitrary code written in JavaScript (e.g. on GitHub), many developers use var self = this and then use self instead of this to reference the current object.

What is the rationale behind this approach?

like image 780
Scholle Avatar asked Aug 11 '12 22:08

Scholle


People also ask

What is var self this?

As others have explained, var self = this; allows code in a closure to refer back to the parent scope.

Why is self needed instead of this in JavaScript?

In the JavaScript, “self” is a pattern to maintaining a reference to the original “this” keyword and also we can say that this is a technique to handle the events. Right now, “self” should not be used because modern browsers provide a “self” as global variable (window.

What is self keyword in JavaScript?

The keyword self is used to refer to the current class itself within the scope of that class only whereas, $this is used to refer to the member variables and function for a particular instance of a class.


4 Answers

The value of this is contextual. Writing var self = this is a way to save the value of this in one context so that it can be used in another.

Example:

function Test() {
    var self = this;
    console.log(this);
    setTimeout(function() {
        console.log(this);
        console.log(self);
    }, 1000);
}

Prints:

Test {}
Window 11918143#comment15869603_11918143
Test {}

Notice that the value of this has changed, but we can still refer to the original value using self.

This works because functions in JavaScript "close over" the variables in their lexical scope (which is just a more technical way of saying that the inner function can see variables declared in the outer function). This is why we write var self = this; the variable self is available to all inner functions, even if those functions don't execute until long after the outer function has returned.

like image 117
Wayne Avatar answered Oct 21 '22 04:10

Wayne


When you are using a callback in jQuery, for example, you may want to reference the parent function's this variable, which takes a different value once you are in another function:

$('#foo').click(function() {
  var self = this;

  $.get('foo.php', function(data) {
    // In here, self != this

    $(self).text(data);
  });
});

In this case, replacing $(self) with $(this) would not work. Basically, you're storing this in a variable for later use.

like image 43
Blender Avatar answered Oct 21 '22 03:10

Blender


Usually when you have a nested function declaration inside some code but you want to refer to the "parent" function from inside the "child" function.

Ext.define('MyPanel', {
    extend: 'Ext.panel.Panel',

    title: 'My Panel',

    initComponent: function() {

        var self = this;

        Ext.applyIf(self, {
            items: [
                {
                xtype: 'button',
                text: 'MyButton',
                handler: function() {
                    console.log(this); //the button
                    console.log(self); //the panel
                }}
            ]
        });

        self.callParent(arguments);
    }
});

Ext.onReady(function() {

    var p = new MyPanel({
        renderTo: Ext.getBody()
    });


});​

Example:

http://jsfiddle.net/8F4UN/

like image 39
Neil McGuigan Avatar answered Oct 21 '22 05:10

Neil McGuigan


Let me give a somewhat more technical explanation. When you access a variable in Javascript, the interpreter looks for the value of the variable in what's known as the scope stack. You can think of it as a stack of Objects. The interpreter will look first at the top of the stack. If the variable isn't defined in that scope object, it will look at the object beneath it. If it's not there, the interpreter looks another level down until it hits the bottom of the stack.

Initially, the only scope object in the stack is the global object. A variable is either there or not. When you call a function, the interpreter pushes a new object onto the scope stack--to be used for storing local variables. When you access var1, the interpreter will first look in the local scope object. If it's there, then it'll use the value stored there. If it's not, it moves on to the scope object further down the stack--which happens to be the global scope.

When you create a function within a function, something interesting happens. The interpreter will create what's known as an "activation object". It's basically a snapshot of the local scope object of the outer function. This activation object becomes associated with the inner function. When the inner function is called, the activation object is push onto the scope stack before the local scope (i.e. the local scope would still be at the top). Access of a variable in the inner function means the interpreter will first check the local scope object, then the activation object, then the global scope object.

By definition, the this variable always exists in the local scope of a function. It always refers to the implicit first argument. When you call a plain-o function, the compiler passes null as this. The variable exists, but points to null. A search for this would never look beyond the local scope object.

The purpose of the assignment to self is basically to fool the interpreter, so that it would look beyond the local scope of the inner function. When you access self in the inner function, the interpreter wouldn't find it in the local scope. So it checks the activation object. Provided that the self = this statement occurs before the creation of the inner function, self would exist in the activation scope object, pointing to the this object seen by the outer function.

like image 42
cleong Avatar answered Oct 21 '22 05:10

cleong