Everyone wants to be an expert, but what is an expert? Over the years, I’ve met two types of people called “experts.” An expert is someone who knows every tool in the language inside and out, and makes sure to use every bit of it, whether it helps or not. Expert two also knows every syntax, but they are choosy about what to use to solve a problem, considering many factors, both code related and irrelevant.

Can you guess which expert we would like to have on our team? If you said expert two, you’re right. They are developers who focus on writing readable JavaScript code that others can understand and maintain. They can make complex things simple. But “readability” is rarely certain — in fact, it is largely based on subjective perception. So what should experts aim for when writing readable code? Is there a clear right and wrong choice? Yes, it depends.

Obvious choice

To improve the developer experience, TC39 has added many new features to ECMAScript in recent years, including mature patterns borrowed from other languages. A new feature in ES2019 is array.prototype.flat (), which takes an argument indicating depth or Infinity and flattens an Array. If no parameter is given, the depth defaults to 1.

Before adding this feature, we need to flatten an array to a single layer using the following syntax.

let arr = [1.2[3.4]]

;[].concat.apply([], arr)
// [1, 2, 3, 4]
Copy the code

When we add flat(), the same functionality can be expressed in a single, descriptive function.

arr.flat()
// [1, 2, 3, 4]
Copy the code

Is the second line more readable? The answer is yes. In fact, both experts would agree.

Not every developer knows that Flat () exists. But they don’t need to, because flat() is a descriptive verb that can convey the meaning of what is happening. It is much more intuitive than concat.apply().

This is one of the few cases where there is a clear answer to the question of whether the new grammar is better than the old one. Two experts, each familiar with both grammars, would choose the second. They choose a single line of code that is shorter, clearer, and easier to maintain.

But the choices and trade-offs are not always decisive.

Health checking

The magic of JavaScript is that it is so versatile. It is widely used on the web for a reason. Whether you think that’s a good thing or a bad thing is another matter.

But with this versatility comes the paradox of choice. You can write the same code in many different ways. How do you determine which approach is “right”? Unless you understand the options available and their limitations, you can’t even start making decisions.

Let’s take the example of functionally programmed map(). I’ll show you through various iterations, all of which produce the same result.

This is the simplest version of our map() example. It uses the minimum number of characters and only one line of code. This is our baseline.

const arr = [1, 2, 3]
let multipliedByTwo = arr.map(el => el * 2)
// multipliedByTwo is [2, 4, 6]
Copy the code

The following example adds only two characters: parentheses. Is there any loss? And what do we get? Is it any different that a function with multiple arguments always needs to use parentheses? I think so. There is no harm in including them here, and it improves consistency when you inevitably write a function with multiple arguments. Prettier actually enforced this constraint when I wrote this, because she didn’t want me to create an arrow function without parentheses.

let multipliedByTwo = arr.map((el) = > el * 2)
Copy the code

Let’s take it one step further. We added braces and carriage returns. Now, this is starting to look more like a traditional function definition. If you have a keyword as long as the logic of the function, it may seem like overcorrection. However, if the function is longer than one line, this extra syntax is required. Do we assume that we won’t have any other function that has more than one line? This seems highly doubtful.

let multipliedByTwo = arr.map((el) = > {
  return el * 2
})
Copy the code

Next we don’t use arrow functions. We use the same syntax as above, but we have replaced it with the function keyword. This is interesting, because this syntax works in any situation; Any number of arguments or lines doesn’t cause problems, so it’s more consistent. It’s more verbose than our original definition, but is that a bad thing? What impact does this have on a new programmer, or someone fluent in a language other than JavaScript? By contrast, would a person proficient in JavaScript be frustrated by this syntax?

let multipliedByTwo = arr.map(function (el) {
  return el * 2
})
Copy the code

Finally we come to the last option: pass functions only. TimesTwo can be written using any syntax we like. Again, there is no case where passing function names is a problem. But take a step back and think if this is confusing. If you are new to this code base, are you aware that timesTwo is a function and not an object? Of course, map() is meant to give you a hint, but it’s not unreasonable to miss this detail. Where is timesTwo declared and initialized? Is it easy to find? Is it clear what it is doing and how it affects the result? These are important considerations.

const timesTwo = (el) = > el * 2
let multipliedByTwo = arr.map(timesTwo)
Copy the code

As you can see, there’s no clear answer here. But making the right choice for your code base means knowing all the options and their limitations. And know that consistency requires braces, braces, and the return keyword.

When writing code, you have to ask yourself some questions. Performance issues are usually the most common. But when you’re looking at code that does the same thing, your judgment should be based on people — how people consume code.

New is not always better

So far, we have found a clear example of both experts adopting the latest grammar, even if it is not well known. We also looked at an example that raised a lot of questions, but not so many answers.

Now it’s time to dig into the code I’ve written before…… But it was deleted. This is the code that made me an expert for the first time, using a little-known syntax to solve the problem, but for my colleagues it broke the maintainability of our code base.

Deconstructing assignments allows you to untangle values from objects (or arrays). It usually looks something like this.

const { node } = exampleObject
Copy the code

It initializes a variable and assigns a value to it on a line. But it doesn’t have to be.

letnode ; ({ node } = exampleObject)Copy the code

The last line of code uses destruction to assign a value to a variable, but the variable declaration occurs on the line before it. It’s not an outlandish thing to do, but a lot of people don’t know you can do it.

But take a closer look at this code. It imposes an awkward semicolon on code that doesn’t end a line with a semicolon. It wraps the command in parentheses and braces; I have no idea what this is about. It’s not easy to read, and, as an expert, it shouldn’t be in the code I write.

let node
node = exampleObject.node
Copy the code

This code solves this problem. It works, it’s clear what it does, and my colleagues don’t have to look it up. Just because I can deconstruct grammar doesn’t mean I should.

Code is not everything

As we’ve seen, the Expert 2 solutions are rarely obvious from the code alone; But there are clear differences in what code each expert will write. That’s because the code is meant for the machine, and the human interprets it. So there are some non-code factors to consider!

The syntax choices you make for a JavaScript development team are different from the choices you should make for a multilingual team that isn’t immersed in minutias.

Let’s extend the operator (…) Take concat().

The extension operator was added to ECMAScript a few years ago and is widely used. It’s a practical syntax that can do a lot of different things. One of them is the join array.

const arr1 = [1.2.3]
const arr2 = [9.11.13]
const nums = [...arr1, ...arr2]
Copy the code

While the extension operator is powerful, it is not a very intuitive notation. So unless you already know what it does, it’s not terribly helpful. While two experts might safely assume that a team of JavaScript experts is familiar with this syntax, expert two might question whether a team of multilingual programmers is. Instead, expert two might choose the concat() method instead, because it is a descriptive verb that you can understand from the context of the code.

This code gives us the same numeric results as the extension operator example above.

const arr1 = [1.2.3]
const arr2 = [9.11.13]
const nums = arr1.concat(arr2)
Copy the code

This is just one example of how human factors influence code selection. For example, a code base that is approached by many different teams may have to hold more stringent standards and may not be able to keep up with the latest and strongest syntax. Then, from a perspective outside the source code, you consider other factors in your toolchain that make it easier or harder for people to work on that code. There is code that can be structured in a way that is hostile to testing. There is some code that gets you bogged down in future extensions or feature additions. Some of the code is not performing well enough to handle different browsers. All of this will factor into expert 2’s recommendations.

Expert 2 also considered the effect of naming. But to be honest, even they don’t get it right most of the time.

conclusion

Experts do not prove themselves by using every specification; They prove themselves by knowing the norms well enough to use appropriate grammar wisely and make sound decisions. That’s how experts become multipliers — and that’s why they create new ones.

So what does this mean for those of us who consider ourselves experts or aspire to be? This means that writing code requires asking yourself a lot of questions. It means thinking about your developer audience in a real way. The best code you can write is code that does some complex business, but is essentially code that can be understood by someone reviewing your code base.

No, it’s not easy. And often there is no clear answer. But that’s something you should think about when you write every function.

English text: alistapart.com/article/hum…