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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

MATLAB数值计算

MATLAB数值计算

莫勒 / 喻文健 / 机械工业出版社 / 2006-6 / 35.00元

《MATLAB数值计算》是关于数值方法、MATLAB软件和工程计算的教材,着重介绍数学软件的熟练使用及其内在的高效率算法。主要内容包括:MATLAB介绍、线性方程组、插值、方程求根、最小二乘法、数值积分、常微分方程、傅里叶分析、随机数、特征值与奇异值、偏微分方程。《MATLAB数值计算》配备大量MATLAB例子源代码及习题,其中涉及密码学、Google网页分级、大气科学和图像处理等前沿问题,可以帮......一起来看看 《MATLAB数值计算》 这本书的介绍吧!

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

在线压缩/解压 CSS 代码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具