Arrows have been part of JavaScript from the beginning. In the first JavaScript, it was recommended to wrap inline script code in HTML comments. This can prevent browsers that do not support JavaScript from displaying your code by error. For plain text. You may have written code like the following:
<script language="javascript"> <!-- document.bgColor = "brown"; // red // --> </script> <script language="javascript"> <!-- document.bgColor = "brown"; // red // --> </script>
Old browsers will see two unsupported tags and a comment, which only newer browsers that support JavaScript will parse as JavaScript code.
To support this weird feature, the browser's JavaScript engine treats also represents a single-line comment. The difference from HTML is that in HTML, the part before --> is the comment content, while in JavaScript, the line after --> is the comment .
Only when --> appears at the beginning of a line, it indicates that the arrow is a comment, because in other cases, --> is an operator (goes to).
function countdown(n) { while (n-->0) // "n goes to zero" alert(n); blastoff(); } function countdown(n) { while (n-->0) // "n goes to zero" alert(n); blastoff(); }
The above code can actually run. Looping until n is 0 is not a new feature of ES6, but combined with familiar features, it is very misleading. Can you figure out how the above code works? You can find the answer on Stack Overflow.
Of course there is an arrow, that is the less than or equal operator <=, maybe you can find a place to use arrows, but let’s stop and look at an arrow we have never seen before:
So, what does => mean? This is what this article will discuss.
First, let’s talk about functions.
Ubiquitous function expressions
An interesting feature of JavaScript is that any time you need a function, you can easily create them.
For example, to bind a click event to a button:
$("#confetti-btn").click( $("#confetti-btn").click(
jQuery’s .click() method requires a function as a parameter. We can easily create a function in place:
$("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); }); $("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); });
Writing code like this is the most natural thing for us now. But before JavaScript became popular, this style of code still looked a bit strange because there were no such features in other languages. In 1958, Lisp had function expressions, also called lambda functions, a feature that had not existed in C, Python, C#, and Java for many years.
Now, these four languages all have lambda expressions, and newer languages generally have built-in lambda expressions. JavaScript now supports this feature, thanks to developers of libraries that rely heavily on lambda expressions, which has driven widespread adoption.
JavaScript has a slightly verbose syntax compared to several other languages:
// A very simple function in six languages. function (a) { return a > 0; } // JS [](int a) { return a > 0; } // C++ (lambda (a) (> a 0)) ;; Lisp lambda a: a > 0 # Python a => a > 0 // C# a -> a > 0 // Java // A very simple function in six languages. function (a) { return a > 0; } // JS [](int a) { return a > 0; } // C++ (lambda (a) (> a 0)) ;; Lisp lambda a: a > 0 # Python a => a > 0 // C# a -> a > 0 // Java
Arrow function
ES6 introduces a new syntax for writing functions:
// ES5 var selected = allJobs.filter(function (job) { return job.isSelected(); }); // ES6 var selected = allJobs.filter(job => job.isSelected()); // ES5 var selected = allJobs.filter(function (job) { return job.isSelected(); }); // ES6 var selected = allJobs.filter(job => job.isSelected());
When you need a function with only one parameter, the syntax of the arrow function can be simplified to Identifier => Expression, directly omitting the function and return keywords, as well as the parentheses and the trailing semicolon.
To write a function with multiple (or no parameters, or Rest parameters and parameter default values, or destructured parameters) parameters, you need to surround the parameters with parentheses:
// ES5 var total = values.reduce(function (a, b) { return a + b; }, 0); // ES6 var total = values.reduce((a, b) => a + b, 0); // ES5 var total = values.reduce(function (a, b) { return a + b; }, 0); // ES6 var total = values.reduce((a, b) => a + b, 0);
Arrow functions can also work perfectly with some tool function libraries, such as Underscore.js and Immutable. In fact, all the examples in the Immutable documentation are written in ES6, and many of them already use arrow functions.
In addition to using an expression in the function body, arrow functions can also contain a statement block. Recall the example we mentioned before:
// ES5 $("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); }); // ES5 $("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); });
The following is how to write the arrow function:
// ES6 $("#confetti-btn").click(event => { playTrumpet(); fireConfettiCannon(); }); // ES6 $("#confetti-btn").click(event => { playTrumpet(); fireConfettiCannon(); });
It should be noted that arrow functions using statement blocks will not automatically return a value, and return must be used explicitly to return a value.
One more word of advice, when using an arrow function to return an object, always use parentheses to surround the returned object:
// create a new empty object for each puppy to play with var chewToys = puppies.map(puppy => {}); // BUG! var chewToys = puppies.map(puppy => ({})); // ok // create a new empty object for each puppy to play with var chewToys = puppies.map(puppy => {}); // BUG! var chewToys = puppies.map(puppy => ({})); // ok
Because empty object {} and empty statement block {} look exactly the same, ES6 will always treat the { immediately following => as the beginning of a statement block instead of the beginning of an object, then puppy => {} is parsed as an arrow function without a function body, and the return value is undefined.