Var Self = This

var self = this?

This question is not specific to jQuery, but specific to JavaScript in general. The core problem is how to "channel" a variable in embedded functions. This is the example:

var abc = 1; // we want to use this variable in embedded functions

function xyz(){
console.log(abc); // it is available here!
function qwe(){
console.log(abc); // it is available here too!
}
...
};

This technique relies on using a closure. But it doesn't work with this because this is a pseudo variable that may change from scope to scope dynamically:

// we want to use "this" variable in embedded functions

function xyz(){
// "this" is different here!
console.log(this); // not what we wanted!
function qwe(){
// "this" is different here too!
console.log(this); // not what we wanted!
}
...
};

What can we do? Assign it to some variable and use it through the alias:

var abc = this; // we want to use this variable in embedded functions

function xyz(){
// "this" is different here! --- but we don't care!
console.log(abc); // now it is the right object!
function qwe(){
// "this" is different here too! --- but we don't care!
console.log(abc); // it is the right object here too!
}
...
};

this is not unique in this respect: arguments is the other pseudo variable that should be treated the same way — by aliasing.

What underlies this JavaScript idiom: var self = this?

See this article on alistapart.com. (Ed: The article has been updated since originally linked)

self is being used to maintain a reference to the original this even as the context is changing. It's a technique often used in event handlers (especially in closures).

Edit: Note that using self is now discouraged as window.self exists and has the potential to cause errors if you are not careful.

What you call the variable doesn't particularly matter. var that = this; is fine, but there's nothing magic about the name.

Functions declared inside a context (e.g. callbacks, closures) will have access to the variables/function declared in the same scope or above.

For example, a simple event callback:

function MyConstructor(options) {  let that = this;
this.someprop = options.someprop || 'defaultprop';
document.addEventListener('click', (event) => { alert(that.someprop); });}
new MyConstructor({ someprop: "Hello World"});

Why do we need var self = this in classes in Javascript?

There's no reason why you can't use this directly there (and I would say it would be better for readability if you did).

However, the var self = this; is often needed in situations like the following (basically, any asynchronous action like event binding, AJAX handlers etc, where the resolution of this is deferred until it equals something else);

function SeatReservation(name, initialMeal) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);

setTimeout(function () {
alert(self.name); // otherwise, this is window; use self to keep a reference to the "SeatReservation" instance.
}, 100);
}

What is the rationale behind the var self = this approach?

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.

JavaScript - var self = this; self is undefined

You're passing the method, brain.login, as a function that has no owner. You're just passing the function reference. You need to do brain.login.bind(brain).

Difference between bind and var self=this?

Given that you're targeting Node.js which implements ES2015 you are better off using arrow functions.
Arrow functions have what is called a lexical this, which means that the variable this in an arrow function is treated like a normal variable and will be closed over when you create the function.

So your code becomes:

retval.then((argument) => {
console.log("argument"+JSON.stringify(argument));
// "this" will inherit the value of the outside scope
this.stateSetting(argument);
});

If targeting ES5 (older browsers), then I'd favor the .bind style rather than var self = this. It's more structured and closer to a functional approach, which makes the code easier to reason about like you must have discovered by using promises. It also seems to be slightly more performant.

how to do `var self = this` inside es6 class?

How can we do like var self = this; as we used to do in ES5?

You can do it exactly like you did in ES5 - ES6 is completely backward-compatible after all:

class Point {
constructor(x) {
this.x = x;
var self = this;
this.toString = function() {
return self.x;
};
}
}

However, that's really not idiomatic ES6 (not talking about const instead of var). You'd rather use an arrow function that has a lexical-scoped this, so that you can avoid this self variable completely:

class Point {
constructor(x) {
this.x = x;
this.toString = () => {
return this.x;
};
}
}

(which could even be shortened to this.toString = () => this.x;)

Is var self = this; a bad pattern?

As others have said: This "extra variable" is (at some level) the only way to get about the fact that this is a special expression and thus, being not a variable, is not bound in an execution context/closure.

However, what I think you are asking (or what I really want to answer) is:

Should one put var self = this at the top of every method/constructor?

Summary

While I tried this once, and had the same question, I no longer use this approach. Now I reserve the construct for when I need access in a closure. To me it adds a little "hey, this is what I really want!" semantic to my code:

this -> this and self -> this (but really that) in a closure

Questions ala carte:

...Although this is commonly done, it feels a bit wrong. What I'm hoping to find in this question is a better way to deal with this, or a something to convince me this is quite alright.

Do what feels right to you. Don't be afraid to try one method and switch back later (but please try to remain consistent within each project :-)

Is this the standard way to keep the correct bindings around? Should I standardize on using 'self' everywhere, unless i explicitly need 'this'.

"self" is the most common name used. As per above, I prefer the opposite approach -- to use this except when a closure binding is required.

..if it's considered a bit evil and why.

Evil is a silly subjective term (albeit fun sometimes). I've never said it was evil, just why I do not follow the approach. Some people tell me I am "evil" for not using semi-colons. I tell them they should actually come up with good arguments and/or learn JavaScript better :-)

I'm aware there's also the 'apply' built-in javascript function to explicitly define scope when calling a method. Is it better?

The problem with apply/call is that you must use them at point of the function invocation. It won't help if someone else calls one of your methods as the this may already be off. It's most useful for doing things like the jQuery-style callbacks where the this is the element/item of the callback, etc.

As an aside...

I like to avoid "needing self" on members and thus generally promote all member functions to properties where the receiver (this) just "flows through", which is normally "as expected".

The "private" methods in my code begin with a "_" and if the user calls them, that's on them. This also works better (is required, really) when using the prototype approach to object creation. However, Douglas Crockford disagrees with this "private" approach of mine and there are some cases where the look-up chain may thwart you by injecting an unexpected receiver:

Using the "self" bound in the constructor also locks the upper limit of the look-up chain for a method (it is no longer polymorphic upward!) which may or may not be correct. I think it's normally incorrect.

Happy coding.



Related Topics



Leave a reply



Submit