March 29th, 2022
JavaScript is a fun but highly effective programming language that has grown like none we've ever seen before. Due to the flexible nature of the JavaScript language there comes freedom in how we want our we applications to be structured.
Common ways to build web applications today are usually related to popular libraries like React. Experienced developers will often tell you to "do what works best for you" when you ask for tips on which tool to use to use for your project when you're comparing one to another.
Unfortunately this freedom can bring up another issue where we can get carried away and grow accustomed to writing code that works for ourselves and not others.
Here is an example of what I mean:
if (!_TEST_ && store.env === 'test') {
if (args._handledCode) {
const errorCodes = getHandedCode(args._handledCode)
args.finalResult?.code &&
errorCodes[0] !== 'all' &&
!(errorCodes.indexOf(args.finalResult?.code) !== -1) &&
toast(`${args.finalResult?.code}:${args.finalResult?.error}`, {
type: 'error',
})
}
}
This is an old example of a code in production that I had to try to understand when debugging an issue. args
is an object that destructs { apiBufferResult, reqOptions }
but there is no mention of what data type _handledCode
is or if it will break the app at some time when removing those lines. Only the developer that wrote that code understands what is happening there. Why is this a problem, you ask? Because now we have no choice but to leave this code untouched and wait for the next developer to get confused like how I was if I can't reach the author who wrote this code!
This post will go over 7 JavaScript Code Practices Your Teammates Will Love You For. The tips in this post are coming from my opinions and experiences as a Team Lead Full Stack Engineer with more of a focus on the Front End side of things, so I assure you that these tips can help you become more valuable as a teammate and they work.
I cannot stress this enough! I absolutely love working with teammates that have a habit of documenting their functions:
/**
* @function
* @description If the value corresponding to the key attribute of an item
* in the array is equal to the value passed in, the value corresponding
* to key1 of the item is returned
* @param {array} arr
* @param {string} key
* @param {string} value
* @param {string} key1
* @returns {string}
*/
matchInArray({
arr,
value,
key,
key1,
}: {
arr: {}[]
value: any
key: string
key1: string
}) {
!u.isArr(arr) && (arr = u.array(arr))
for (let i = 0; i < arr.length; i++) {
if (arr[i]?.[key] == value) return arr[i][key1]
}
}
There's a couple things to note here. The name matchInArray
might be sufficient enough to pass without the extra JSDoc comments above with a little bit of thinking and common sense. But we're still not sure. The comments provided above clears any mystery we come up with. We know what to expect as input and we have a full vision on what is currently handled and what is not. You're allowing other people to own your code.
Lets take a look at this without the comments and i'll explain why I might have a problem with this code:
matchInArray({
arr,
value,
key,
key1,
}: {
arr: {}[]
value: any
key: string
key1: string
}) {
!u.isArr(arr) && (arr = u.array(arr))
for (let i = 0; i < arr.length; i++) {
if (arr[i]?.[key] == value) return arr[i][key1]
}
}
Okay, at least I know that this function intends to find a matching value in the array arr
using one of the keys. But read this: arr[i]?.[key] == value
. What can we expect a value will be from arr[i]?.[key]
? It can be another array, an object, a number, the full alphabet from A to Z, anything.
Let's say the author who wrote this code is unreachable and we now have to develop a new feature within the same day that involves arrays. One task we need to accomplish is to have a function that grabs a matching product id number from some array.
Since we can't reuse matchInArray
because it is doing a comparison using ==
(which means "5"
will return true
for the number 5
) we have to create a separate function. Since our new task is similar to the goal that matchInArray
tries to accomplish, our new function will most likely have a similar name. We now have two functions that sound similar. Developers who try to understand our code are now having to face a dilemma of what function they can use for a similar task.
Moral of the story? Try to help your teammates avoid walking on a rocky surface. They shouldn't have to worry about where to step next.
Your teammates will love it when they read changes in code that follow the same coding style. Installing prettier
is sometimes not enough, for example this is prettier doing auto formatting for this array:
const dividedStyleKeys = [
'position',
'left',
'top',
'right',
'bottom',
'width',
'height',
]
If it's common in the repo to see code that disables prettier to allow them all to be on the same line, then it should be a hint that you should do something similar:
// prettier-ignore
const dividedStyleKeys = ['position', 'left', 'top', 'right', 'bottom', 'width', 'height']
This reduces 9 lines of code down to 2.
When you create unit tests for your code you are establishing "official"ness. It removes mystery, validates your code and yields confidence to the people around you.
It's a done deal. We know everything about your code and that it accomplishes its task.
It becomes a more productive development experience when there are less doubts.
There are two kinds of questions. The first is the kind that will quietly struck a nerve to the person you are asking from.
Here is a question that doesn't spark a nerve:
"I couldn't find an answer on google about this code, why do we need this part?"
And here is one that will:
"What is this supposed to do and why do we need this part?"
The second question is rude because it shows that you did not put in the time to work it out yourself and are discrediting yourself from being a reliable teammate. You are taking someone else's time away for your laziness and you're showing that you don't care enough.
I once had an employee that asked tons of questions like these and more than 90% of the time (I am not even exaggerating this percentage) I found the answer to his questions on the front page of google search results. This person had a bachelors degree and had a great looking resume but it didn't end up matching his work ethic.
Don't get me wrong. We love to get asked questions but not the kind of questions that are found within the first 3 minutes of searching through a google search result.
It's JavaScript. There's information everywhere.
Not everyone can compose functions elegantly as it takes time and practice to get better at function composition, so we won't go into detail in that. But as far as writing or naming functions it's incredibly impactful in your value as a teammate when written in a way where it reads like a book.
There's a section in a great book called Functional Light JS
about filter
that explains this perfectly.
For example, when implementing a filterer function. In real life when we think of filtering things we think of filtering the bad stuff out such as a water filtration.
But in programming some concepts behave the opposite way.
As a Lead I can instantly confirm that I love it when teammates catch a bug in my (or their) code before I do and speak up about it. This prevents users from potentially encountering the bug on accident and it's one less bug we all would have to pull our hairs over.
I highly value teammates that catch bugs on their own, speak up about it and not waste another minute to let that bug fly.
Most of the time it isn't a big deal when your parameters are declared in no particular order until your functions become like this:
When working with functions like this we're sort of having to bounce up and down to hunt down the parameter. There are some cases where it would be fine such as ordering them where required ones start at the top or to put some emphases (like title if it's relative to a blog post or something). But if there's no good reason, I highly recommend doing everyone a favor and just sort them otherwise you're being like the person in step 4.
And that concludes the end of this post! I hope you found this valuable and look out for more in the future!
Tags
© jsmanifest 2023