What is this? where did this come from?

“What is this?” This is not really a question to be answered with the conceptual mind or mental analysis, but more of a way of being with things with an openness and inquisitiveness into “what is.”

STEVEN GOODHEART, Helpful Suggestions on Working with the “What is this?” Koan

Somehow I found myself confused over some basic consents of JavaScript, even though I used them on a daily base. So I returned for a refreshement about the “this” and what to do when it’s lost.

JavaScript “this” keyword is the basic method to referrer to the current object. This will not be the place to talk about this, This time I’ll summarize the ways to handle cases where we lose this. (And yes, I’m looking for opportunities to use this inside the sentence)

Where this is lost:

this.exist = "Nope, wrong answer :-(";
var f = {
exist: true,
thisOne: function(){
console.log(this.exist); // true
setTimeout(function(){
console.log(this.exist); // Nope, wrong answer :-(
},0)
},
}
f.thisOne();

The old solution I used ages ago was to save the this as a different variable:

var f = {
exist: true,
thisOne: function(){
var that = this;
setTimeout(function(){
console.log(that.exist); // true
},0);
}
}
f.thisOne();

But using it is just showing that you don’t really understand how this works. Or unfamiliar with the proper ways to handle this situation.

Today, with the ES6 arrow function, you have a simple workaround:

var f = {
exist: true,
thisOne: function(){
setTimeout(()=>{
console.log(this.exist); // true
},0)
}
}
f.thisOne();

The difference between a regular function and an arrow function is that the arrow takes the ‘this’ context lexically.

bind()

But what do you do if you really are out of scope, and can’t perform on your “this”. Like on web component. Or when you work on a different “this”:

this.name = "It's not me :-(";
var me = {
name: 'Me!!! :-)',
showMe : function(){
console.log(this.name);
}
}
var whoAmI = me.showMe;
whoAmI(); // It's not me :-(

This is where we find the first out the three: bind()

var whoAmI = me.showMe.bind(me);
whoAmI(); // Me!!! :-)

The bind() create an exotic bound function, big words that set the “this” of the object to the one sent into the method. That way you can operate on the “this” as within the object.

If we return to the timeout problem, we will change it into:

var f = {
exist: true,
thisOne: function(){
setTimeout(this.timeout.bind(this),0);
},
timeout : function(){
console.log(this.exist);
}
}
f.thisOne(); // true

Note that this time, using the arrow function for the timeout will not refer to the current object, but to its caller:

this.exist = "nope :-(";
var f = {
exist: true,
thisOne: function(){
setTimeout(this.timeout.bind(this),0)
},
timeout: ()=>{
console.log(this.exist);
}
}

f.thisOne(); // nope :-(

A cool example of the use of bind(), is to make a object “come to live”, by placing a pure function on it:

var us = [ {
name: 'Me',
race: 'hedgehogs'
},{
name:'You',
race: 'perfect'
},
...
];
function showMe(){
console.log(this.name + ' is a ' + this.race);
}

var me = showMe.bind(us[0]);
me(); // Me is a hedgehogs

call()

But if all we need is to execute a function with some this, there is a shorter way. Using the call method, we can pass the “this” as an argument.

var us = [ {
name: 'Me',
race: 'hedgehogs'
},{
name:'You',
race: 'perfect'
},
...
];
function showMe(description){
console.log(`${this.name} is a ${description} ${this.race}`);
}
showMe.call(us[0], 'fat'); // Me is a fat hedgehogs

Back to see how object come to life with pure type functions:

var us = [ {
name: 'Me',
race: 'hedgehogs'
},{
name:'You',
race: 'perfect'
},
...
];

function showMe(){
console.log(this.name + ' is a ' + this.race);
}

us.forEach(x => showMe.call(x));
// Me is a hedgehogs
// You is a perfect

apply()

The last function on the list is the “apply()”, but since this post became too long, I’ll just mention that while call() expects all parameters to be passed individually. The apply() expects an array of parameters.

Note: On strict mode, the functions will not return the global “this” as on the examples, but “undefined”.

So next time you are sitting in meditation, asking “what is this”, don’t look for an inner answer, but change the code to answer “how can I pass ‘this'”.