fos.alex
fos.alex

Reputation: 5627

Binding different this scope to ES6 => function operator

After experimenting with inheriting contexts with the => feature that ES6 gives us I noticed that the this context can never be changed. Example:

var otherContext = {
  a: 2
};
function foo() {
  this.a = 1;

  this.bar = () => this.a;

}

var instance = new foo;
instance.bar(); // returns 1
instance.bar.bind(otherContext)(); // returns 1

Without the => operator and using the function keyword:

function foo() {
  this.a = 1;

  this.bar = function () {
    return this.a;
  }
}
var instance = new foo;
instance.bar(); // returns 1
instance.bar.bind(otherContext)(); // returns 2

Therefore, if we receive a function from an external call or just have a function in a variable, how can we be sure if we are going to be able to bind a different this to it or if it will just inherit it from somewhere?

It sounds dangerous that javascript does not tell you anything, one might fall for a VERY subtle and difficult bug.

Upvotes: 8

Views: 4513

Answers (2)

Quentin
Quentin

Reputation: 943214

It is effectively just new syntax for bind, so this doesn't introduce anything new in the way of gotchas.

var otherContext = {
  a: 2
};
function foo() {
  this.a = 1;
  this.bar = function () { return this.a }.bind(this);
}

var instance = new foo;
log(instance.bar()); // returns 1
log(instance.bar.bind(otherContext)()); // returns 1

function log(value) { 
  document.body.appendChild(
    document.createTextNode(value)
  );
}

Therefore, if we receive a function from an external call or just have a function in a variable, how can we be sure if we are going to be able to bind a different this to it or if it will just inherit it from somewhere?

Because either:

  1. You'll have written that function in the first place or
  2. You'll have written a specification for how to call your function so that people know to pass in a function which makes use of this from a context you choose.

Upvotes: 8

Jeremy J Starcher
Jeremy J Starcher

Reputation: 23863

When using the function keyword, the rules binding this are fairly straight forward.

Either the invoking call sets this (be it through .call, .apply or JavaScript setting this when the function is called as a method) or this gets a well-known value:

  • In normal mode, this will be the window object.
  • In strict mode, this will be undefined.

With arrow functions, the rule is even simpler.

  • There is no this keyword. (nor arguments, or a few others)

Which means that, inside an arrow function, this is always bound to the outside context, because that is where this comes from.

So, in summary:

When using arrow functions, the value of this always comes from the outside context.

Upvotes: 8

Related Questions