DEV Community

Cover image for Write better code by following these JavaScript best practices

Write better code by following these JavaScript best practices

dcodes on May 18, 2023

Whether you're a seasoned developer looking for ways to refine your coding style or a beginner eager to grasp the essentials, this blog post is for...
Collapse
 
lexlohr profile image
Alex Lohr • Edited
  • #1: adopt a formatter/config and stick with it. It'll save you so much time.
  • #3: your shorter code might fall if y is falsy, like an empty string or zero. Use ?? instead of || unless this effect is intended.
  • #4: Avoid comments unless they serve a purpose, ie explaining the reasoning behind a piece of code where it's not obvious or adding helpful tooltips in lsp-powered editors/IDEs with JSDoc + markdown.
  • #5: in some cases, you need to influence CSS further than just setting a class, lest you needed classes for a thousand colors. CSS variables are a good solution.
  • #7: for..of is actually less performant than for..in and even less than for. The main use of for..of is to handle Iterators. But if performance doesn't matter too much, why not use the array methods like forEach/map/reduce? Know your loops and use the correct one. #9 seems to be missing.
  • #11: While immutability is a nice pattern, it can also be a performance problem, wasting CPU cycles and memory on unnecessary object creation and garbage collection. That being said, if you mutate arguments, make it obvious to the user.
  • #12: I really like the pattern of mixing await and .catch. It's much terser than try/catch and allows a more fine-grained error Handling.
  • #14: you really shouldn't use var anymore when there are const and let.
Collapse
 
johnlandgrave profile image
John Landgrave

In #3 the two implementations are equivalent, since the more verbose version just has if (y). I would argue that you should do a more explicit if (y === 0) or if (typeof y === 'undefined') or whatever is appropriate for your code. Relying on "falsiness" introduces a whole class of bugs if you aren't careful with your code.

Collapse
 
reacthunter0324 profile image
React Hunter

It's great practice examples. I can remember many things by this.
Thank you

Collapse
 
dcodes profile image
dcodes

Glad you liked it!

Collapse
 
szeredaiakos profile image
szeredaiakos
  1. Coding style.
    One of the most important part for me is the reduction of cognitive load on my team. It is of the utmost importance that my teammates use their own styles and language dialects. Adoption of a consistent style at a surface sounds great but it piles on busy work for both juniors and some masters. I say, if you can't read other dialects, rather than coercing others to conform, you should focus on becoming a better programmer. Automated
    formatting tools, for
    example are espe-
    cially dangerous in
    this
    regard. The-
    y make the code down
    right unread
    able sometimes.
    A very light formatting standard, however, is always welcome to reduce load on version control.

  2. Naming.
    This is an important step of the refactoring phase of a grain of work. It is not a practice, it's more like procedure.

  3. Shorthands and acronyms.
    If your grandma knows what it is, you can use it.

  4. Comments
    Comments are the first step towards refactoring. Further, if you need to document your code you are already doomed. Well, a 100k line project might benefit from some documentation.

  5. SoC
    In our company we don't sell CSS. It is NOT a concern. The only reason why one should break away code at a functional faultline is to reduce noise.

  6. Globals
    As long as a module is clean elegant and to the point, this should not have any effect. For anything else one can build application and context level global libraries.

  7. For...of
    Looping pattern should be left to the developer. Again, cognitive load reduction. Here, if a dev uses a looping scheme which he is not familiar with, increases the chance of errors.

  8. SRP.
    The author is not the only one who does not know what the single responsibility principle is.

  9. Class hoisting
    Know your language .. I guess. I do understand why this needs to be pointed out, but why specifically class hoisting? Did author ran into it? The resulting exception is particularly self explanatory.

  10. Mutation
    If you can't handle and maintain mutation you should open up a bakery instead.

  11. Promises
    The author confuses promises and dirty data/code.

  12. Nesting
    Yes, nesting is pain if you can't fit the entire hierarchy on your screen. Turning an 8k monitor portrait is not an elegant solution. Sausage conditions work, but they are sausage. And returns in the middle of functions require your team to be comfortable with it.

  13. Do optimize for loops.
    Why the iterator? There is much more precise way to show this.

Conclusion:
Best practices are still a scam. :)

Collapse
 
khaledmv profile image
Khaled Hossain

Great! Thanks

Collapse
 
dcodes profile image
dcodes

Glad you found it useful!

Collapse
 
efpage profile image
Eckehard

7. Use for...of Instead of for Loops

referring to CanIUse, for...of was not supported by some browers for a long time. First release of Safari, that supported for...of was October 2022. So, without babel it might break your code on older browsers. for...in is generally safe to use or - as mentioned below - use forEach/map/reduce instead

Collapse
 
hilleer profile image
Daniel Hillmann

Thanks for this article. Certainly some good points and considerations along!

Under point 11. Handle Promises Correctly I wonder why you recommend to try-catch always. IMO there's no reason to try-catch any promise, unless you plan to specifically handle the error thrown - if you do not, then there's no reason to try-catch it and simply throw the same error again. Furthermore, what's the reason you recommend to re-throw the error like this, after one has handled the error acconrdigly:

  } catch (error) {
    // Handle your errors here...
    throw new Error(error)
  }
Enter fullscreen mode Exit fullscreen mode

You can simply throw the already defined error - in fact, the error object do not take an error as argument but a string:

  } catch (error) {
    // Handle your errors here...
    throw error;
  }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ant_f_dev profile image
Anthony Fung

Great list!

There's one important thing to keep in mind about mutating function arguments. If a function takes an array and it contains references to objects, returning a new array with references to the same objects (i.e. creating a shallow copy) could cause confusion. This is because a modification to an object in one array will also affect the contents of the other array: they both refer to the same object(s).

If this isn't the intention, one way to do a deep copy is to convert an array/object into JSON, and the parsing it again.

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍