By Dmitri Pavlutin
Translator: Front-end wisdom
Source: dmitripavlutin.com
Like it and see. Make it a habit
In this paper,
GitHub
Github.com/qq449245884…Has included more categories of previous articles, as well as a lot of my documentation and tutorial material. Welcome Star and Perfect, you can refer to the examination points for review in the interview, I hope we can have something together.
The arrow feature is worth popularizing. Its syntax is concise and uses a lexical binding to bind this, which makes it ideal for a callback. In this article, we’ve gone through five best practices for solving learning so that we can learn more about arrow functions and get more out of them.
1. Arrow function name inference
The arrow function in JS is anonymous: the function’s name attribute is “”.
( number => number + 1 ).name; / / = > 'Copy the code
During debugging sessions or call stack analysis, anonymous functions are marked as anonymous. Unfortunately, the Anonymous program does not provide any clues about the code being executed.
Here is a debug session for code that executes anonymous functions:
The call stack on the right consists of two functions labeled anonymous, and nothing useful can be gleaned from such call stack information.
Fortunately, function name inference (a feature of ES2015) can detect function names under certain conditions. The idea of name inference is that JS can determine the arrow function name from its syntactic position: from the name of the variable holding the function object.
Let’s look at how function name inference works:
const increaseNumber = number => number + 1;
increaseNumber.name; // => 'increaseNumber'
Copy the code
Since the variable increaseNumber holds the arrow function, JS has decided to use the name of the function increaseNumber. Therefore, the name of the arrow function is ‘increaseNumber’.
Practice # 1:
A good practice is to use function name inference to name arrow functions.
Now let’s examine a debug session with code that uses name inference:
Because the arrow functions have names, the call stack provides more information about the code being executed.
-
The handleButtonClick function name indicates that a click event occurred
-
GainCounter increments a counter variable.
2. Use inline mode whenever possible
An inline function is a function that has only one expression. I like the arrow feature, the ability to write short inline functions.
For example, don’t use the long form of the arrow function:
const array = [1, 2, 3];
array.map((number) => {
return number * 2;
});
Copy the code
When the arrow function has only one expression, the curly braces {} and return statements can be easily removed:
const array = [1, 2, 3];
array.map(number => number * 2);
Copy the code
Practice # 2:
When a function has only one expression, it is a good practice to use the inline arrow function format
3. Fat arrows and comparison operators
The comparison operators >, <, <=, and >= look similar to the f fat arrow =>(which defines the arrow function). There is some confusion when using these comparison operators in inline arrow functions.
For example, we define an arrow function that uses the <= operator
const negativeToZero = number => number <= 0 ? 0 : number;
Copy the code
The presence of two symbols => and <= on the same line can be misleading.
To clearly distinguish the fat arrow from the comparison operator, we can use parentheses:
const negativeToZero = number => (number <= 0 ? 0 : number);
Copy the code
The second option is to define the arrow function in a longer form:
const negativeToZero = number => {
return number <= 0 ? 0 : number;
};
Copy the code
These refactorings remove the confusion between the fat arrow symbol and the comparison operator.
Practice 3:
If the arrow function contains the operators >, <, <=, and >=, it is a good practice to wrap the expression in parentheses or deliberately use a longer arrow function form.
4. Construct a normal object
Using an object literal in an inline arrow function raises a syntax error:
const array = [1, 2, 3];
// throws SyntaxError!
array.map(number => { 'number': number });
Copy the code
JS considers curly braces to be code blocks, not object literals.
To solve this problem, add a pair of parentheses to the object literal:
const array = [1, 2, 3];
// Works!
array.map(number => ({ 'number': number }));
Copy the code
If the object literal has many attributes, we can use line breaks and still keep the arrow function inline
const array = [1, 2, 3];
// Works!
array.map(number => ({
'number': number
'propA': 'value A',
'propB': 'value B'
}));
Copy the code
Practice 4:
When you use an object in an inline arrow function, you wrap the changed object in a pair of parentheses.
5. Watch out for excessive nesting
The syntax for arrow functions is very short and good. However, the side effect is that it can be obscure when many arrow functions are nested.
Let’s consider the following case. When the button is clicked, the request to the server is initiated, and when the response is ready, the items are logged to the console:
myButton.addEventListener('click', () => {
fetch('/items.json')
.then(response => response.json());
.then(json => {
json.forEach(item => {
console.log(item.name);
});
});
});
Copy the code
There are three levels of nesting of arrow functions, and it takes time and effort to understand what the code does.
To improve the readability of nested functions, the first approach is to introduce each variable containing the arrow function that concisely describes what the function does.
const readItemsJson = json => {
json.forEach(item => console.log(item.name));
};
const handleButtonClick = () => {
fetch('/items.json')
.then(response => response.json());
.then(readItemsJson);
};
myButton.addEventListener('click', handleButtonClick);
Copy the code
The refactoring extracts the arrow function into the variables readItemsJson and handleButtonClick. The nesting level is reduced from 3 to 2. Now we can more easily understand the functionality of the script.
Better yet, you can refactor the entire function using async/await syntax, which is a great way to solve function nesting:
const handleButtonClick = async () => {
const response = await fetch('/items.json');
const json = await response.json();
json.forEach(item => console.log(item.name));
};
myButton.addEventListener('click', handleButtonClick);
Copy the code
Practice 5:
It is good practice to avoid excessive nesting of arrow functions by extracting arrow functions as stand-alone functions or using async/await syntax whenever possible.
6. Summary
Arrow functions in JS are anonymous. To make debugging more efficient, it is a good practice to use variables to hold arrow functions, which allows JS to infer function names.
Embedded arrow functions are handy when the function body has an expression.
The operators >, <, <=, and >= look similar to the fat arrow =>, and you must be careful when using these operators in inline arrow functions.
Object literal syntax {prop: ‘value’} is similar to code block {}. Therefore, when placing an object literal in an embedded arrow function, you need to wrap it in a pair of parentheses: () => ({prop: ‘value’}).
Finally, excessive nesting of functions obscures the code’s intent. A good way to reduce the nesting of arrow functions is to extract them into variables. Alternatively, try using better features such as async/await syntax.
If you have any other suggestions for arrow functions, please leave a comment.
The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.
Original text: dmitripavlutin.com/javascript-…
communication
This article is updated every week, you can search wechat “big move the world” for the first time to read and urge more (one or two earlier than the blog hey), this article GitHub github.com/qq449245884… It has been included and sorted out a lot of my documents. Welcome Star and perfect. You can refer to the examination points for review in the interview.