esafwan esafwan - 1 month ago 7
Javascript Question

Es6 Arrow function to normal js

I have been trying to understand es6 arrow function. I read some articles introducing it. But I'am still not getting it fully.

For example I have this code:

sortedArticles(): Article[] {
return this.articles.sort((a: Article, b: Article) => b.votes - a.votes);
}


It sorts the below array:

[
new Article('Angular 2', 'http://angular.io', 3),
new Article('Fullstack', 'http://fullstack.io', 2),
new Article('Angular Homepage', 'http://angular.io', 1),
];


How would the same code look in plain old js? I am not able to fully get it.

Answer

It would look like this if you just converted the arrow function to a function function:

sortedArticles(): Article[] {
    return this.articles.sort(function(a: Article, b: Article) { return b.votes -  a.votes;});
// ---------------------------^^^^^^^^------------------------^^^-------------------------^^
}

...but note that there's more going on there than ES2015 ("ES6"). The : Article[] part is saying that sortedArticles returns an array of Article. (And similarly the : Article qualifiers on a and b.) That's not JavaScript at all. It looks like TypeScript.

The pure JavaScript version would just drop those type annotations:

sortedArticles() {
    return this.articles.sort(function(a, b) { return b.votes -  a.votes;});
}

But TypeScript's "fat arrow" functions work the same way ES2015's arrow functions do, so let's continue on that basis:

There are four fundamental differences1 between arrow functions and function functions:

  1. They close over this and arguments (the pseudo-array of runtime args), they don't have their own versions of those like function functions do.

  2. They can have a concise body rather than a verbose one (but they can have a verbose body as well).

  3. They cannot be used as constructors. E.g., you can't use new with an arrow function. A consequence of this is that arrow functions don't have a prototype property on them (since it's only used if the function is used with new). Another consequence is that they can't use new.target, which only makes sense in a constructor.

  4. There is no generator syntax for arrow functions. E.g., there is no arrow equivalent to function *foo() { ... }.

These three functions are all effectively the same, since they don't use this or arguments:

// A `function` function
var f1 = function(x) {
    return x * 2;
};

// An arrow function with a verbose body
var f2 = x => {
    return x * 2;
};

// An arrow function with a concise body
var f3 = x => x * 2;

(If they used this or arguments, they would not be the same.)

Note that the concise body doesn't have a { after the => and must contain a single top-level expression (which can of course have subexpressions), which is used as the return value.


1 (You'll find people telling you there's a fifth: That arrow functions cannot have a name. That's a myth. Arrow functions can have names; the arrow functions above have true names, f2 and f3 respectively. It's not just the variables that have names, the functions do as well.)