[javascript] What underlies this JavaScript idiom: var self = this?

I saw the following in the source for WebKit HTML 5 SQL Storage Notes Demo:

function Note() {
  var self = this;

  var note = document.createElement('div');
  note.className = 'note';
  note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
  note.addEventListener('click', function() { return self.onNoteClick() }, false);
  this.note = note;
  // ...
}

The author uses self in some places (the function body) and this in other places (the bodies of functions defined in the argument list of methods). What's going on? Now that I've noticed it once, will I start seeing it everywhere?

This question is related to javascript scope closures

The answer is


It should also be noted there is an alternative Proxy pattern for maintaining a reference to the original this in a callback if you dislike the var self = this idiom.

As a function can be called with a given context by using function.apply or function.call, you can write a wrapper that returns a function that calls your function with apply or call using the given context. See jQuery's proxy function for an implementation of this pattern. Here is an example of using it:

var wrappedFunc = $.proxy(this.myFunc, this);

wrappedFunc can then be called and will have your version of this as the context.


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

However, it's now 2018 and ES6 is widely supported by all major web browsers. The var self = this; idiom isn't quite as essential as it once was.

It's now possible to avoid var self = this; through the use of arrow functions.

In instances where we would have used var self = this:

function test() {
    var self = this;
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", function() {
        console.log(self.hello); // logs "world"
    });
};

We can now use an arrow function without var self = this:

function test() {
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", () => {
        console.log(this.hello); // logs "world"
    });
};

Arrow functions do not have their own this and simply assume the enclosing scope.


It's a JavaScript quirk. When a function is a property of an object, more aptly called a method, this refers to the object. In the example of an event handler, the containing object is the element that triggered the event. When a standard function is invoked, this will refer to the global object. When you have nested functions as in your example, this does not relate to the context of the outer function at all. Inner functions do share scope with the containing function, so developers will use variations of var that = this in order to preserve the this they need in the inner function.


As mentioned several times above, 'self' is simply being used to keep a reference to 'this' prior to entering the funcition. Once in the function 'this' refers to something else.


The variable is captured by the inline functions defined in the method. this in the function will refer to another object. This way, you can make the function hold a reference to the this in the outer scope.


I think the variable name 'self' should not be used this way anymore, since modern browsers provide a global variable self pointing to the global object of either a normal window or a WebWorker.

To avoid confusion and potential conflicts, you can write var thiz = this or var that = this instead.


Yes, you'll see it everywhere. It's often that = this;.

See how self is used inside functions called by events? Those would have their own context, so self is used to hold the this that came into Note().

The reason self is still available to the functions, even though they can only execute after the Note() function has finished executing, is that inner functions get the context of the outer function due to closure.


function Person(firstname, lastname) {
  this.firstname = firstname;

  this.lastname = lastname;
  this.getfullname = function () {
    return `${this.firstname}   ${this.lastname}`;
  };

  let that = this;
  this.sayHi = function() {
    console.log(`i am this , ${this.firstname}`);
    console.log(`i am that , ${that.firstname}`);
  };
}

let thisss = new Person('thatbetty', 'thatzhao');

let thatt = {firstname: 'thisbetty', lastname: 'thiszhao'};

thisss.sayHi.call(thatt);


Actually self is a reference to window (window.self) therefore when you say var self = 'something' you override a window reference to itself - because self exist in window object.

This is why most developers prefer var that = this over var self = this;

Anyway; var that = this; is not in line with the good practice ... presuming that your code will be revised / modified later by other developers you should use the most common programming standards in respect with developer community

Therefore you should use something like var oldThis / var oThis / etc - to be clear in your scope // ..is not that much but will save few seconds and few brain cycles


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to scope

Angular 2 - Using 'this' inside setTimeout Why Is `Export Default Const` invalid? How do I access previous promise results in a .then() chain? Problems with local variable scope. How to solve it? Why is it OK to return a 'vector' from a function? Uncaught TypeError: Cannot read property 'length' of undefined Setting dynamic scope variables in AngularJs - scope.<some_string> How to remove elements/nodes from angular.js array Limiting number of displayed results when using ngRepeat A variable modified inside a while loop is not remembered

Examples related to closures

Store a closure as a variable in Swift How to map to multiple elements with Java 8 streams? groovy: safely find a key in a map and return its value Exception: Serialization of 'Closure' is not allowed JavaScript closures vs. anonymous functions Don't understand why UnboundLocalError occurs (closure) Closure in Java 7 How should I call 3 functions in order to execute them one after the other? Why aren't python nested functions called closures? Passing parameters in Javascript onClick event