5 Best Practices to Write Quality Arrow Functions

栏目: IT技术 · 发布时间: 4年前

内容简介:The arrow function deserves its popularity. The arrow function syntax is concise, bindsIn this post, you’ll read 5 best practices to get even more benefits from the arrow functions.The arrow function in JavaScript is an anonymous function. Which means that

The arrow function deserves its popularity. The arrow function syntax is concise, binds this lexically, fits great as a callback function.

In this post, you’ll read 5 best practices to get even more benefits from the arrow functions.

1. Arrow function name inference

The arrow function in JavaScript is an anonymous function. Which means that the name property of an arrow function is an empty string:

( number => number + 1 ).name; // => ''

During a debug session or call stack analysis the anonymous functions are marked as anonymous . Unfortunately, anonymous gives no clue about the code being executed.

The following picture shows a debug session of a code that uses anonymous arrow functions:

5 Best Practices to Write Quality Arrow Functions

The call stack on the right side consists of 2 functions. It’s difficult to understand the control flow.

Fortunately, the function name inference can put names on the arrow functions. The idea of name inference is that JavaScript can determine the arrow function name from its syntactic position.

Let’s see how function name inference works:

const increaseNumber = number => number + 1;

increaseNumber.name; // => 'increaseNumber'

Because the variable increaseNumber holds the arrow function, JavaScript decides that 'increaseNumber' could be a good name for that function. Thus the arrow function receives the name 'increaseNumber' .

A good practice is to use function name inference to name the arrow functions.

Now let’s check a debug session with code that uses name inference:

5 Best Practices to Write Quality Arrow Functions

Because the arrow functions have names, the call stack gives more information about the code being executed:

handleButtonClick
increaseCounter

2. Inline when possible

An inline function is one which body consists of one expression. I like about arrow functions the ability to compose short inline functions.

For example, instead of using the long form of an arrow function:

const array = [1, 2, 3];

array.map((number) => { 
  return number * 2;
});

You could easily remove the curly braces { } and return statement when the arrow function has one expression:

const array = [1, 2, 3];

array.map(number => number * 2);

Here’s my advice:

When the function has one expression, a good practice is to inline the arrow function.

3. Fat arrow and comparison operators

The comparison operators > , < , <= and >= look similar to the fat arrow => that defines the arrow function.

When these comparison operators are used in an inline arrow function, it creates some confusion.

Let’s define an arrow function that uses <= operator:

const negativeToZero = number => number <= 0 ? 0 : number;

The presence of both symbols => and <= on the same line is misleading.

To make your intent clear, the first option is to wrap the expression into a pair of parentheses:

const negativeToZero = number => (number <= 0 ? 0 : number);

The second option is to deliberately define the arrow function using a longer form:

const negativeToZero = number => {
  return number <= 0 ? 0 : number;
};

These refactorings eliminate the confusion between fat arrow symbol and comparison operators.

If the arrow function contains the operators > , < , <= and >= , a good practice is to wrap the expression into a pair of parentheses or deliberately use a longer arrow function form.

4. Constructing plain objects

An object literal inside an inline arrow function triggers a syntax error:

const array = [1, 2, 3];

// throws SyntaxError!
array.map(number => { 'number': number });

JavaScript considers the curly braces as a code block, rather than an object literal.

This problem is solved when the object literal is wrapped into parentheses:

const array = [1, 2, 3];

// Works!
array.map(number => ({ 'number': number }));

You could also use an alternative form by specifying the properties in a new line. This form might be more readable when having lots of properties:

const array = [1, 2, 3];

// Works!
array.map(number => ({
  'number': number
  'propA': 'value A',
  'propB': 'value B'
}));

My recommendation:

Wrap object literals into a pair of parentheses when used inside inline arrow functions. 

5. Be aware of excessive nesting

The arrow function syntax is short, which is good. But as a side effect, it could be cryptic when nesting many arrow functions.

Let’s consider the following scenario. When a button is clicked, a request to server starts, and when the response is ready the items are logged to console.

myButton.addEventListener('click', () => {
  fetch('/items.json')
    .then(response => response.json());
    .then(json => {
      json.forEach(item => {
        console.log(item.name);
      });
    });
});

The arrow functions are 3 levels nesting. It takes effort and time to understand what the code does.

When the arrow functions are nested, to increase readability, the first approach is to introduce variables that hold each arrow function. The variable should describe concisely what the function does (seearrow function name inferencebest practice).

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);

The refactoring extracts the arrow functions into variables readItemsJson and handleButtonClick . The level of nesting decreases from 3 to 2. Now, it’s easier to understand what the script does.

Even better you could refactor the entire function to use async/await syntax, which is a great way to solve the nesting of functions:

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);

Resuming:

A good practice is to avoid excessive nesting of arrow functions by extracting them into variables as separate functions or, if possible, embrace async/await syntax.

6. Conclusion

The arrow functions in JavaScript are anonymous. To make debugging productive, a good practice is to use variables to hold the arrow functions, which allows JavaScript to infer the function name.

An inline arrow function is handy when the function body has one expression.

The operators > , < , <= and >= look similar to the fat arrow => . Care must be taken when these operators are used inside inline arrow functions.

The object literal syntax { prop: 'value' } is similar to a code of block {} . So when the object literal is placed inside an inline arrow function, you need to wrap it into a pair of parentheses: () => ({ prop: 'value' }) .

Finally, the excessive nesting of functions obscures the code intent. A good approach to reduce the arrow functions nesting is to extract them into variables. Alternatively, try to use even more powerful features like async/await syntax.

What’s your favorite coding best practices? Leave a comment below!


以上所述就是小编给大家介绍的《5 Best Practices to Write Quality Arrow Functions》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

谁说商业直觉是天生的

谁说商业直觉是天生的

[美] 戴夫·帕特奈克 (Dev Patnaik)、[美] 彼得·莫特森 (Peter Mortensen) / 马慧 / 万卷出版公司 / 2010-07 / 36.00

《Wired to Care》是帕特奈克集近年来在创新顾问公司 Jump Associates 实务经验,与史丹佛大学教学经验之大成,虽然《Wired to Care》定位为一本用设计创新方法谈企业管理的书,但本书,活像是一本近代的设计史,从以销售为设计目标的Raymond Loewy谈起,到以人为设计中心的OXO GOOD GRIPSSwivelPeeler削皮刀。由此作者向我们揭示了企业如何运......一起来看看 《谁说商业直觉是天生的》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

随机密码生成器
随机密码生成器

多种字符组合密码