1

Here is a sample of Javascript Object using traditional function definition

const obj = {
  a: 10,
  b: 20,
  add: function(){
     return this.a + this.b;
  }
}

obj.add()  // returns 30

When I use arrow function in add, the context of this in add changes to global i.e. windows object in browser.

const obj = {
  a: 10,
  b: 20,
  add: () => {return this.a + this.b}
}

obj.add()  // this context is global(windows) of it returns NaN

So in order to bind the context back to obj, I implemented call as below:

obj.add.call(obj)  // Still the context is global(windows) and returns NaN

So 2 things that I didn't understand is:

  1. Why didn't the arrow function bind obj context by default as in traditional function definition?
  2. Why didn't the obj's add method get bind to the obj even if I've passed it explicitly?
Pax
  • 1,251
  • 1
  • 8
  • 19
  • 1
    *"1. Why did the arrow function didn't bind obj context by default as in traditional function definition?"* Because it closes over the context in which it's created, which is the context *around* the `const obj = {}`. Object literals don't have their own context. (You are **not** the first person to assume they did! Not by far. :-) ) *"2. Why didn't the obj's add method get bind to the obj even if I've passed it explicitly?"* Same answer: Arrow functions *close over* `this`. They don't have `this` set by how they're called like traditional functions do. – T.J. Crowder Feb 06 '21 at 15:47
  • And what about the first case? Using traditional function declaration? @T.J.Crowder – Pax Feb 06 '21 at 15:51
  • 1
    I'm probably covering ground covered by the linked answers, but FWIW, check out [this fiddle](https://jsfiddle.net/tjcrowder/fpL51hmx/). – T.J. Crowder Feb 06 '21 at 15:51
  • Traditional functions get `this` set by how they're called, not where they're defined. When you call a function via an object property (`obj.add()`), `this` within the call is set to `obj`. More [here](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) and [here](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback). (FWIW, I also go into this [on my old anemic blog](http://blog.niftysnippets.org/2008/04/you-must-remember-this.html) and in my recent book [links in my profile if you're interested.) – T.J. Crowder Feb 06 '21 at 15:53
  • So there are limitations to Js, `bind`/`call` doesn't work for all context? Is that what I shall interpret from now? – Pax Feb 06 '21 at 15:54
  • 1
    It's not a limitation, it's a feature. If you want to control `this` when you call the function (including syntax like `obj.add()` or using `bind` or `call` to set `this`), use a traditional function (created via the `function` keyword or method syntax). If you want a function that closes over `this`, use an arrow function. The chief motivation for adding arrow functions was to have them close over `this` so they'd be useful as callbacks within object methods. – T.J. Crowder Feb 06 '21 at 15:56
  • 1
    I thought arrow functions were replacement to traditional functions. Seems that both go hand to hand :) Thank you for your explaination. Appreciated it. – Pax Feb 06 '21 at 15:59
  • 1
    Right, they're an adjunct, not a replacement. My pleasure! Happy coding! – T.J. Crowder Feb 06 '21 at 16:01

0 Answers0