Just an MD file to put one of the best js good practices that I have realised as Frontend Developer
for (attribute in array) {
// π
const container = document.getElementById('container');
...
}
The code above make the engine work any harder than it must. We traverse the DOM to find the "container" element each timeβhighly inefficient!
const person = 'David';
const age = 28;
// π
const message = person + ' has ' + age ' years old';
// Better π
const message = `${person} has ${age} years old`;
Template literals are created using the backtick character (```), and they offer many advantages. This reduces the chances of any typing-related errors and helps us write cleaner code.
// Bad π
var message = 'Hello World';
// Use let or const instead π
const message = 'Hello World';
The let
keyword allows us to create variables that can change, and const
keyword allows us to create variables whose value cannot be reassigned. Keep in mind that the const keyword only prevents reassignment, it does not make the variable immutable.
// π
const a = new Array();
a[0] = 'Hello';
//Better π
const a = ['Hello'];
const array = ['Hello, 'World', 'Team'];
const newArray = ['Cuba', ...array];
This JavaScript functionality is for array and objects also.
const obj = {
kind: 'Hapiness',
hobby: 'Music',
place: 'Europe'
teamName: 'Havana Club Rum π'
};
// Bad π
const kind = obj.kind;
const hobby = obj.hobby;
const place = obj.place;
// Better (with destructuring) π
const {kind, hobby, place} = obj;
Destructuring simply implies breaking down a complex structure into simpler parts.
const companies = ["Microsoft", "Google", "Apple"];
const length = companies.length;
// π If not necesarry strict this iterator use "for of" instead
for(let i = 0; i < length; i++) {
console.log(companies[i]);
}
//Better π
for(company of companies) {
console.log(company);
}
With a loop, we don't have to keep track of the total length of the array or the current index. This can reduce code complexity when creating nested loops.for...of. By the way, avoid nested loops as much as possible. Even, if itβs neccesary use classic βforβ iterator, the length of array would be best declare outside loop, just as wroten.
function showMessage() {
return new Promise((resolve) => setTimeout(() => resolve("Hello World!"), 2000));
}
// Classic call
showMessage.then(data=>{
console.log(data);
})
//Better call with await π
console.log(await showMessage());
You can use the keyword to create asynchronous functions, which always return a promise either explicitly or implicitly. Asynchronous functions that you create can take advantage of the keyword by stopping execution until the resolution of returned promises.
const nums = [1,2,3,4,5,6,7,8];
// π
const tempNums = nums.filter(function(n) {
...
})
// Better π
const tempNums = nums.filter(n => ...)
Arrow functions make the functional elements of JavaScript more appealing to the eye and easier to write. Also they do not define a scope, instead being within the parent scope. This prevents many of the issues that can occur when using the keyword.
// π₯³
const urls = ["https://google.com", "https://wikipedia.org"];
const inf = await Promise.all(urls.map(async url => await fetch(url)));
Run promises in parallel can make your app much faster and more responsive. If your tasks don't rely on the results from one another, simply wrap them in and run them with βPromise.all"
By the way, Rxjs library is also a very important technology to use which manage async code. Observables are not native part of javascript but itβs top used.
const items = ["ice cream","fruits","milk"];
items.splice(2,1);
// π
const myFn = function() {...}
// π
function myFn() {...}
Unless you want to take advantage of Function behavior and properties, prefer function expressions. Function declarations are hoisted and although it can be useful sometimes, avoid them as they introduce weird behavior to the code and it is not always obvious what's happening.
// π
function myFn(array) {
for (const index in array){
array[index] *= 2;
}
return array;
}
// π
function myFn(array) {
return array.map(n => n * 2);
}
Ensure your functions are not changing data they are called with or data in the scope where they are created.
// π
if(data && data.someThing && data.someThing.name = 'Hello World') {...}
// π
if(data?.someThing?.name = 'Hello World') {...}
Get rid of those nested checks and use the β?β operator.
10 === 10 // true
It is considered best practice to always use strict equality when comparing.
Don't trust things passed to JSON methods β.stringifyβ and β.parseβ. Try to catch them to make sure they don't fail and break your code.
The nullish coalescing operator makes sure that null and undefined values are not picked and it is perfect for cases where you want to ensure that there is a value or fallback to a default value.
-
- Don't initialize variables with βundefinedβ.
- Always initialize your declarations.
- Organize your declarations.
- Declarations on top.
- Always const variables first.
- For key values map on json files, if possible organize the keys alphabetically.
- Avoid unnecessary comments.
- Use TypeScript as much as possible.
- Functions and methods should do one thing only (Single Responsability Principle).
- Use Facade Pattern when working with inherit (better implementation with TS).
- Always have a default case for switch statements.
- Avoid the βnewβ keyword because they can slow compilers down.
- Keep ternaries simple.
- Avoid nesting or chaining loops.
- Add semicolons, always!
- Never trust data you don't create.
- Avoid repeating yourself with utilities (DRY).
- β¦