Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Settimeout, bind and this

Here I have copied code snippet from MDN : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

function LateBloomer() {
  this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.declare = function() {
  console.log('I am a beautiful flower with ' +
    this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();  
// after 1 second, triggers the 'declare' method

The most confusing part is : window.setTimeout(this.declare.bind(this), 1000);

I understand how this works and this inside settimeout is always bound to global object.I know there can be var self or var that inside bloom function.

There are two this in that line but which this refers to what and how that works is totally confusing.

How works?

like image 646
Siddharth Avatar asked Aug 03 '16 07:08

Siddharth


People also ask

What is third argument in setTimeout?

In short, third argument is the argument user needs to pass the the reference function [1st argument] given to setTimeout which is promise. We can call "arguments carry forward" to this feature.

How do I pass context in setTimeout?

If you're using TypeScript, you can pass the function as a parameter, like this: setTimeout(this. tip. destroy, 1000);

What is the use of setTimeout () in Javascript?

setTimeout() The global setTimeout() method sets a timer which executes a function or specified piece of code once the timer expires.

Is setTimeout deprecated?

We all know that passing a string to setTimeout (or setInterval ) is evil, because it is run in the global scope, has performance issues, is potentially insecure if you're injecting any parameters, etc. So doing this is definitely deprecated: setTimeout('doSomething(someVar)', 10000);


2 Answers

First of all read this article, which offers a very nice explanation about how this works.

.bind(this, args) just helps you to pass your this context inside your function (because inside it in your example by default this is undefined or refers to window).

Also bind is a nice alternative to this:

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  var self = this;
  window.setTimeout(self.declare, 1000);
};

And as the last point in es6 you can do it in this way:

window.setTimeout(() => {
  //do some stuff
}, 1000);

instead of

window.setTimeout(function () {
  //do some stuff
}.bind(this), 1000);

this allow you to not think about this.

like image 126
Sergei Panfilov Avatar answered Oct 22 '22 00:10

Sergei Panfilov


MSDN defines Function.prototype.bind() as,

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

By using .bind(this) we are passing this to the function declare

See this snippet.

function LateBloomer() {
  console.log(this.constructor);
  this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.undefinedbloom = function() {
  window.setTimeout(this.declare, 1000);
};

LateBloomer.prototype.declare = function() {
  console.log(this.constructor);
  console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();
flower.undefinedbloom();

In the function undefinedbloom we are just calling the declare function. So the object will be the window object. It doesn't have property petalCount so its undefined.

In the function bloom we are binding the this of LateBloomer to the declare function by which we will have access to the LateBloomer's object petalCount.

this in JavaScript is a very difficult to fathom at first.

MDN Link: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this

like image 23
naveen Avatar answered Oct 22 '22 00:10

naveen