1

I have heard someone saying that Javascript arrow functions can be used to "solve some scope related problems".

So far I've known that the main advantage of JavaScript arrow functions is by saving syntax or allow implicit behavior.

1) Shorter ("sugar") syntax example:

()=>{...}
let myFunction = ()=>{...}

Are shorter than:

function() {...}
function myFunction() {...}

2) Implicit behavior as in this reduce() example:

let prices = [1, 2, 3, 4, 5];
let result = prices.reduce( (x,y)=> x+y );
// Reduce data from x to y (reduce needs return, which is included implicitly). Result will be 15 (1+2+3+4+5 are reduced to 15, in this case).

I fail to associate these and other examples with scope. I know that there was a problem with scope in which a variable declared inside a function with var couldn't be inherited to a sub function and this problem was solved when const and let where introduced (they allow such inheritance).

So what are the main scope problems arrow functions come to solve beside of suggesting sugar syntax and some implicit behaviors?

Osi
  • 1
  • 3
  • 9
  • 30
  • 2
    Possible duplicate of [Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?](https://stackoverflow.com/questions/34361379/arrow-function-vs-function-declaration-expressions-are-they-equivalent-exch) – Andreas Mar 03 '18 at 08:21
  • 1
    Arrow functions don't have their own `this`, thus preserving the outer `this` context when used as callbacks. – connexo Mar 03 '18 at 08:25
  • @connexo I assume that by "outer this" you mean to the latest available `this` before the last arrow function? – Osi Mar 03 '18 at 08:41
  • https://javascript.info/object-methods#this-in-methods and https://javascript.info/object-methods#arrow-functions-have-no-this – connexo Mar 03 '18 at 08:45
  • @user9303970 he means a closure, the same way it works for every other variable. That also means that you can not `bind(obj)` to an arrow function. – Thomas Mar 03 '18 at 08:50
  • It's the people who say "scope" when they mean the *`this` context* or *receiver*. Don't believe everything you hear. Variable scope works just like normal in arrow functions, there are no problems with it. – Bergi Mar 03 '18 at 09:36
  • @Bergi interesting way of putting it. Thanks. You might want to make this an answer plus expanding with a sentence on what Thomas said one comment above? – Osi Mar 03 '18 at 09:45
  • When you say _"solve some scope related problems"_ i think you mean context related problems. the dynamic nature of `this` context can be misleading sometimes, you think it refers to one thing but it actually points to a different thing. with arrow functions the context is set in a lexical (static) way at design time. very similar to the way variables scope works. with this in mind, you need to be careful when **not** to use arrow functions, for example when you are adding a method to the prototype and needs `this` to reference the caller or when you want to use a constructor function (`new`) – Sagiv b.g Mar 03 '18 at 11:17

1 Answers1

3

ES6 fat arrow function not only solve your syntax concise and make your code readable but it also has got more advantage than this. In addition, is how the new Arrow Function binds or actually DOES NOT bind it’s own this. Arrow Functions lexically bind their context so this actually refers to the originating context. Now your question would be, what is lexically bind. Let's try to understand by simple example. Consider a small JavaScript code.

const team = {
  members = ['Ankur','Ranjan'],
  teamName = 'Super Squad',
  teamSummary: function(){
    return this.members.map(function(member){
      return `${member} is on team $(this.teamName)`
    }) 
  }
 }

This code would throw TypeError: Can't read property 'teamName' of undefined. You could use bind() method of JavaScript to solve this issue or you can use var self = this and change this.teamName to self.teamName. Both the way is quite good but you can also the arrow function to solve this problem.

const team = {
  members = ['Ankur','Ranjan'],
  teamName = 'Super Squad',
  teamSummary: function(){
  // this === team
  return this.members.map((member) => {
    return `${member} is on team $(this.teamName)`
    }) 
  }
}

So How exactly is ‘lexical this’ allowing us to pass execution context? By using ‘lexical scoping’. Lexical Scoping just means that it uses this from the code that contains the Arrow Function.