rabbitco rabbitco - 2 months ago 11
Javascript Question

Deep understanding: Why do .bind(this) not seem to follow the normal rules when used with new Promise

The following code:

var this_module = {

foo: 'something',

promise: function () {

return new Promise (function(resolve, reject) {

resolve (this.foo);
}.bind(this))
}
}


successfully binds
this
to the
this_module
. I cannot understand why.

The
new
operator normally sets
this
to the object created as part of the constructing call to a given function. This should mean that the constructing call to the Promise function would set
this
to the Promise object. If this is the case then
.bind(this)
should also set the executor function's
this
to the Promise object.

Alternatively
.bind(this)
should set the executor function's
this
to the
this
value of the Promise function (which in the above example should be the global object).

Why is this not the case?

Answer
var this_module = {

  foo: 'something',

  promise: function () {
    return new Promise(function(resolve, reject) {
      resolve(this.foo);
    }.bind(this));
  }

};

Normal rules for this apply. The this in bind(this) occurs within the method promise on this_module, and thus by definition refers to this_module. Therefore, the this within the executor refers to this_module, and can access foo. Nothing surprising is happening here.

As explained in the comments, the this within the executor has nothing to do with any this referring to the new promise. In fact, you cannot access the promise being constructed, by design. Any this referring to the new promise is happening within the Promise constructor, which is invisible to you.

Perhaps the downvotes were due to the fact that this code could be explained quite simply by normal rules for this, but they do seem a bit harsh.

You might consider that what you wrote is precisely equivalent to the following:

var this_module = {

  foo: 'something',

  promise: function () {
    const self = this;

    return new Promise(function(resolve, reject) {
      resolve(self.foo);
    });
  }

};

and is also equivalent to

var this_module = {

  foo: 'something',

  promise: function () {
    return new Promise((resolve, reject) =>
      resolve(this.foo);
    );
  }

};
Comments