The majority of contemporary programming languages support lambda expressions (Python, Ruby, Java?). Simply said, they are expressions that generate functions. First-class functions, which essentially mean sending functions as arguments to other functions or assigning them to variables, are extremely crucial for a programming language to provide.
Function expressions in JavaScript prior to ES6 provides us with an anonymous function (a function without a name).
var anon = function (a, b) { return a + b };
We now have arrow functions in ES6 that offer a more adaptable syntax as well as some added features and difficulties.
// we could write the above example as:
var anon = (a, b) => a + b;
// or
var anon = (a, b) => { return a + b };
// if we only have one parameter we can loose the parentheses
var anon = a => a;
// and without parameters
var () => {} // noop
// this looks pretty nice when you change something like:
[1,2,3,4].filter(function (value) {return value % 2 === 0});
// to:
[1,2,3,4].filter(value => value % 2 === 0);
The fact that arrow functions lack their own this value is one of their main advantages. This is lexically bound to the scope it is contained in. This suggests that we can bid this awful pattern farewell:
class Logger {
dumpData(data) {
var _this = this;
// this dumps data to a file and get the name of the file via a callback
dump(data, function (outputFile) {
_this.latestLog = outputFile;
});
}
}
// using arrow functions
class Logger {
dumpData(data) {
dump(data, outputFile => this.latestLog = outputFile);
}
}
However, there are a few pitfalls to be aware of:
- This should be rather obvious, but since it is lexically bound, there is no way to change it. Neither call() nor apply() will be able to supply a different value for this.
- There are no disagreements.
(function () {console.log(arguments)})(1, 2); // will output [1, 2]
(() => console.log(arguments))(1, 2);
- When returning object literals, exercise caution.
(() => {foo: 1})() // this will return undefined. 'foo: 1' is interpreted as a statement composed of a label and the literal 1
// the correct way should be wrapping it with parenthesis
(() => ({foo: 1}))() // returns Object {foo: 1}
Conclusion
In conclusion, arrow functions are a fantastic addition to the JavaScript language that enable considerably more ergonomic code in a variety of circumstances.
They do, however, have advantages and cons, just like any other characteristic. They ought to serve as an additional resource for us.