3

Note, Related Value of this inside object method?

Given

var obj = {
  property: 5,
  func1: function () {
    console.log(this.property);
  },
  func2: () => {
    console.log(this.property);
  }
}

this would be Window at obj.func2().

When tried setting this to obj using Function.prototype.call(), this was still Window

var obj = {
  property: 5,
  func1: function () {
    console.log(this.property);
  },
  func2: () => {
    console.log(this.property);
  }
}

obj.func2.call(obj);
  1. Is this expected behaviour?

  2. Why does Function.prototype.call() not set the context of obj.func2 to obj?

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177
  • 4
    `this` for arrow functions is captured from the outer context, so it is an expected behaviour. – zerkms Jul 24 '16 at 23:35
  • @zerkms `Function.prototype.call`, `Function.prototype.apply` cannot set `context`:`this` of arrow functions? – guest271314 Jul 24 '16 at 23:36
  • 1
    Nope, http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions-runtime-semantics-evaluation – zerkms Jul 24 '16 at 23:39
  • This is by design. If you want functions where `this` can be re-assigned you MUST use regular functions. Regular functions may also exhibit this behavior if you use `.bind()` – slebetman Jul 24 '16 at 23:49
  • [I essentially found a way to do this](https://stackoverflow.com/a/61830943/1045881) – toddmo May 16 '20 at 01:56

1 Answers1

4

It is expected as per the standard

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment.

That means - you cannot set something that is not defined.

Also, relevant:

The functions are called with the [[Call]] internal slot that sets the this binding as

  1. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).

Which in turn checks

  1. Let thisMode be the value of F’s [[ThisMode]] internal slot.
  2. If thisMode is lexical, return NormalCompletion(undefined).

So, internally it has an additional check on whether the function is lexically scoped (an arrow function) or not.

References:

zerkms
  • 249,484
  • 69
  • 436
  • 539