I was asked the difference between a classical function
and the new modern arrow function
syntax, but it's a little bit hard to explain without examples, so here's the two major differences.
Let's imagine we have a class called Data
, and let's imperatively create two functions.
class Data {
saveFunction;
constructor() {
// Classic Function
this.saveFunction = function (data) {
// save my data
}
// Arrow Function
this.saveFunction = (data) => {
// save my data
}
}
}
These two look identical, but let's dig into the two major differences.
Syntax Differences
So first of all, modern one is shorter, hurray! There's even a bunch of shorthand you can use, such as dropping the parentheses when you have only one parameter, and dropping the curly brackets when you want to return the results of a single expression.
These syntax differences become EXTREMELY useful when you start passing functions around, which happens a lot when we write asynchronous code using Promises, Observables, or even when we need to write callbacks.
Consider the following two implementations. Both are trying to take a list and return the odd numbers.
Classic function style:
[1,2,3,4,5,6].filter(function(item) {
return item % 2;
}
Arrow function style
[1,2,3,4,5,6].filter(item => item % 2);
The lack of parentheses and the automatic return of the value of the expression really help cut down the length here.
The brevity increases the clarity of what's going on, once you know how arrow functions work.
Semantic Differences
There's one more important difference, which is that arrow functions and classical functions actually work slightly different. Classic functions create an "object" and a scope with its own definition of this
, whereas arrow functions don't.
This becomes important in our original example, where we were creating functions inside of our Data class. Within classic functions, this
probably don't refer to the instance you were probably expecting, but arrow functions do.
We can see this by popping the following code is an ES5 transpiler and looking at the classic JavaScript.
class Data {
saveFunction;
currentValue;
constructor() {
// Classic Function
this.saveFunction = function (data) {
// save my data
this.currentValue = {};
}
// Arrow Function
this.saveFunction = (data) => {
// save my data
this.currentValue = {}
}
}
}
Using the transpiler on the TypeScript Playground we get the following ES5:
var Data = /** @class */ (function () {
function Data() {
var _this = this;
// Classic Function
this.saveFunction = function (data) {
// save my data
this.currentValue = {};
};
// Arrow Function
this.saveFunction = function (data) {
// save my data
_this.currentValue = {};
};
}
return Data;
}());
Because the modern version is using a specifically mapped _this
that it creates, the call to this.currentValue
does exactly what we expect, updating the property of the instance. In the classic function , it creates a new property on the function, which is quickly thrown away.
Top comments (1)
Well explained stephen that is so clean and clear.