Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 996
fos.alex Avatar asked Oct 22 '15 15:10

fos.alex


People also ask

What does () => mean in JavaScript?

It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.

How are arrow functions () => {} different than traditional function expressions?

In regular function, arguments will give you list of parameter passed in function, In arrow function arguments is not defined. In regular function, you always have to return any value, but in Arrow function you can skip return keyword and write in single line. In arrow function parameters should be unique.

Does bind work on arrow function?

For similar reasons, the call() , apply() , and bind() methods are not useful when called on arrow functions, because arrow functions establish this based on the scope the arrow function is defined within, and the this value does not change based on how the function is invoked.

Do arrow functions have their own binding to the this keyword?

Arrow functions treat this keyword differently. They don't define their own context since it doesn't have its own this context. They inherit that from the parent scope whenever you call this . this in regular function always refers to the context of the function being called.


1 Answers

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.
like image 55
Quentin Avatar answered Oct 03 '22 16:10

Quentin