DEV Community

Cover image for 25 JavaScript Snippets & Best Practices Every Developer Should Know
Shubham Tiwari
Shubham Tiwari

Posted on

17 3 2 4 2

25 JavaScript Snippets & Best Practices Every Developer Should Know

Hello my frontend developer friends, today i will be discussing some awesome javascript snippets which you may or may not have used but is very useful and used in almost all the web dev projects.

  • I'll be creating my code snippets on Scribbler.live first, which is a fantastic platform that allows you to run a JavaScript Notebook, Online Compiler, and Editor without the need for manual setup.
  • Additionally, I am including a link to code snippets that includes all of the code examples so you can open the snippet and run it yourself to see the results.
  • I will be using scrib.show from scribbler.live, it is equivalent to console.log

Lets dive in...
Table of contents

1. Use const and let

Using const and let are more safer than var as these are scoped to the block in which they are using. let value could be re-assigned later but cannot be re-initialised in the same scope while const can neither be re-initialised nor re-assigned.

// const and let
const awesome = "javascript"
// awesome = "java" // throws error, value cannot be re-assigned
// const awesome = "java" // throws error, cannot be re-initialized

let trending = "React JS"
trending = "Next JS" // allowed, value can be re-assigned
// let trending = "java" // throws error, cannot be re-initialized
Enter fullscreen mode Exit fullscreen mode

2. Default Function Parameters

This avoids undefined when arguments are missing.

// Default Function Parameters
function awesome(name = "javascript") {
  scrib.show(`Trending language is ${name}!`);
}
awesome(); // Trending language is javascript!
Enter fullscreen mode Exit fullscreen mode

3. Template Literals over String Concatenation

This helps in integrating dynamic values inside strings without using "+" and commas

// Template literal strings
// Without template literal
const framework = "React JS"
scrib.show("Javascript has " + framework + " as framework/library");

// With template literal
scrib.show(`Javascript has ${framework} as framework/library`);
Enter fullscreen mode Exit fullscreen mode

4. Object Destructuring

Allows to extract out the keys from an object to use directly instead of using dot notation or square brackets to access key values from an object.

// Object destructuring
const language = {
  name: "Javascript",
  usedIn: "Web development",
  framework: "React JS, Next JS, Vue JS"
}

const { name, usedIn, framework } = language // destructure the properties you want to use
scrib.show(`${name} is used in ${usedIn} and it has multiple frameworks like ${framework}`)
Enter fullscreen mode Exit fullscreen mode

5. Array destructuring

Just like object destructuring, we could do the same with arrays, extracting out its elements using square brackets

// Array destructuring
const frameworks = ["React JS", "Next JS", "Vue JS"]

const [reactjs, nextjs, vuejs] = frameworks
scrib.show(reactjs, nextjs, vuejs)
Enter fullscreen mode Exit fullscreen mode

6. Optional Chaining (?.)

It prevents runtime errors from accessing undefined.

// Optional Chaining
const languages = { javascript: { ext: ".js" } };
scrib.show(languages?.javascript?.ext); // ".js"
scrib.show(languages?.javascript?.library); // undefined
Enter fullscreen mode Exit fullscreen mode

7. Nullish Coalescing Operator (??)

Only falls back if null or undefined, not 0 or false.

// Nullish coelsing
const language = null;
const library = language ?? "javacript";
console.log(library); // "javacript"
Enter fullscreen mode Exit fullscreen mode

8. Short-Circuit Evaluation

If the value is truthy, evaluates to right side value, if the value is falsy like 0, false, null, undefines, evaluates to left side value.

// Short-Circuit Evaluation
const language = true;
const message = language && `Javascript is used is web development? - ${language}`;
scrib.show(message)
Enter fullscreen mode Exit fullscreen mode

9. Ternary Operator

It is the short form of if-else where ? indicateds if and ":" indicates else

// Ternary operator
const library = "ReactJS"
const isJsLibrary = library === "ReactJS" ? `${library} is a JS library` : `${library} is not a JS library`
scrib.show(isJsLibrary)
Enter fullscreen mode Exit fullscreen mode

10. Spread Operator for Objects/Arrays

It spreads the value of an object or array inside another object or array.

// Spread operator with objects
const language1 = {
  name: "javascript",
  ext: ".js"
}

const languages1Extended = {
  ...language1,
  libraries: "axios, react js"
}


// Spread operator with arrays
const languageSet1 = ["java", "python", "rust"]
const languageSet2 = ["javascript", "go", "c++"]
const languages = [...languageSet1, ...languageSet2]

scrib.show(languages1Extended)
scrib.show(languages)
Enter fullscreen mode Exit fullscreen mode

11. Use Array.map() for Transformation

It helps in mapping over array values and adding transformations to each array value like capitalizing each word.

// Transformations using array map method
const languages = [ "java", "python", "rust", "javascript", "go", "c++" ]
const upperCase = languages.map(language => language.toUpperCase())
const capitalize = languages.map(language => language.split("")[0].toUpperCase() + language.split("").slice(1).join(""))
scrib.show(upperCase)
scrib.show(capitalize)
Enter fullscreen mode Exit fullscreen mode

12. Use Array.filter() to Remove Items

This one doesn't need explaination it just simply checks the elements which we want to remove and won't include in the transformed array.

// Removing item using filter
const languages = [ "java", "python", "rust", "javascript", "go", "c++" ]
const webDevLanguages = languages.filter(language => language !== "rust" && language !== "go" && language !== "c++")
scrib.show(webDevLanguages) // [ "java", "python", "javascript" ]
Enter fullscreen mode Exit fullscreen mode

13. Use Array.reduce() for Aggregation

Reduce method allows us to compute multiple values to a single value like summation of multiple values.

// Aggregation using reduce method
const finances = [908000, 209010,400000]
const total = finances.reduce((acc, val) => acc + val, 0); // 1517010
scrib.show(total)
Enter fullscreen mode Exit fullscreen mode

14. Debounce Functions (for Search Inputs)

The debounce function allows us to call a callback function after a delay like 100ms, 1s, etc. It helps in calling apis for searching purpose with a delay to avoid making api calls on every keystroke.

function debounce(callback, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => callback(...args), delay);
  };
}
Enter fullscreen mode Exit fullscreen mode

15. Throttle Function

Throttle functions allows us to limit the number of times a function can be executed in a given time frame.

// Throttle function
function throttle(callback, delay) {
  let shouldWait = false;
  return (...args) => {
    if (!shouldWait) {
      callback(...args);
      shouldWait = true;
      setTimeout(() => (shouldWait = false), delay);
    }
  };
}
Enter fullscreen mode Exit fullscreen mode

16. Deep cloning

It helps to clone an object with nested properties at multiple levels and it is Ssafer than JSON.parse(JSON.stringify(...)) for deep objects.

const language = { name: "javascript", ext: { js: ".js", jsx: ".jsx" } };
const copyLanguage = structuredClone(language);
scrib.show(copyLanguage)
Enter fullscreen mode Exit fullscreen mode

17. Clean try-catch-finally Blocks

try, catch and finally blocks allows us to handle errors efficiently without breaking or stopping the main thread executions.

// Try catch blocks
try {
  // risky code here that could have errors
  throw Error("This is a custom error")
} catch (error) {
  scrib.show("Something went wrong:", error.message); // Something went wrong: This is a custom error
} finally {
  scrib.show("It will run no matter a error is thrown or not")
}
Enter fullscreen mode Exit fullscreen mode

18. Async await with fetch

async/await is a cleaner and more readable way for asynchronous data fetching using fetch method.

// Async await with fetch
async function getData() {
  try {
    const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    const data = await res.json();
    scrib.show(data); // { "userId": 1, "id": 1, "title": "delectus aut autem", "completed": false }
  } catch (err) {
    scrib.show("Error:", err);
  } finally {
    scrib.show("Data fetched successfully")
  }
}
getData()
Enter fullscreen mode Exit fullscreen mode

19. Memoization with Closures

It is used to optimize performance by caching the results of function calls.

function memoize(fn) {
  const cache = {};
  return function (n) {
    if (n in cache) return cache[n];
    return (cache[n] = fn(n));
  };
}
Enter fullscreen mode Exit fullscreen mode

20. Readable Conditionals with Guard Clauses

It helps to avoids deeply nested if statements.

// Guard clause to avoid deeply nested if
const language = {
  name: "javascript",
  ext: ".js",
  library: "axio"
}
function checkLanguage(language) {
  if (!language) return "No language found";
  if (!language.name) return "Name required";
  if (!language.ext) return "Extension required";
  if (!language.library) return "A library name is required";
  return "All good"
}
scrib.show(checkLanguage(language)) // All good
Enter fullscreen mode Exit fullscreen mode

21. Abort Fetch Requests

Sometime a user might click another link or button when a fetch call is getting processed, in that case we could use the abort controller to abort the current fetch call and proceed with the next one.

const controller = new AbortController();
const signal = controller.signal;

fetch("https://jsonplaceholder.typicode.com/todos/1", { signal })
    .catch(err => {
    if (err.name === "AbortError") scrib.show("Request aborted");
  });
controller.abort(); // Request aborted
Enter fullscreen mode Exit fullscreen mode

22. Function Composition

It allows us to combine multiple functions into a single function.

// Function composition
const compose = (...fns) => (val) => fns.reduceRight((acc, fn) => fn(acc), val);

// Example usage
const financeBonusQuarted1 = x => x * 1.25;
const financeBonusQuarted2 = x => x * 2;
const result = compose(financeBonusQuarted1, financeBonusQuarted2)(500000);
scrib.show(result) // 1250000
Enter fullscreen mode Exit fullscreen mode

23. Custom Event Emitter

It just mimics Node.js style event systems.

class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(event, cb) {
    (this.events[event] ||= []).push(cb);
  }

  emit(event, ...args) {
    this.events[event]?.forEach(fn => fn(...args));
  }
}

const emitter = new EventEmitter();

const languages = [ "java", "python", "rust", "javascript", "go", "c++" ]

emitter.on("findLanguages", language => scrib.show(languages.filter(lang => lang === language)));
emitter.emit("findLanguages", "java");
Enter fullscreen mode Exit fullscreen mode

24. Proxy for Reactive Objects

It allows us to track property access, validate values before setting them, freeze some properties, etc.

const language = new Proxy({ name: "Javascript" }, {
  get(target, prop) {
    console.log(`Getting ${prop}`);
    return target[prop];
  },
  set(target, prop, value) {
     scrib.show(`Setting ${prop} to ${value}`); 
     if(typeof value !== "string"){
          scrib.show("Value type should be string");
          return false
     } else {
          target[prop] = value;
          return true
     }  
  }
});
scrib.show(language.name) // Javascript
language.name = "Python"
scrib.show(language.name) // Python
language.extension = ".py"
scrib.show(language.extension) // .py

language.library = 100;
scrib.show(language.library) // undefined as the type is number and it didn't set the property on language
Enter fullscreen mode Exit fullscreen mode

25. Tagged Template Literals

In tagged template literals, you call a function on the template literal itself

// Tagged literals
function strong(strings, ...values) {
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `<strong>${values[i]}</strong>` : '');
  }, "");
}

const language = "JavaScript";
scrib.show(strong`${language} is trending`)
Enter fullscreen mode Exit fullscreen mode

That's it for this post, Let me know if i could do any improvements in this article. Also, do check Scribbler.live website.

You can contact me on -

Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

You can help me with some donation at the link below Thank you👇👇
https://www.buymeacoffee.com/waaduheck

Also check these posts as well

Top comments (5)

Collapse
 
omal_jayamanne_ profile image
Omal Jayamanne

Great article and solid list! One thing I was curious about in the Memoization with Closures example, it uses a simple object as the cache. Do you think using Map instead of a plain object could be more effective in certain cases, especially when the keys are not guaranteed to be strings? Would love to hear your thoughts on that!

Collapse
 
shubhamtiwari909 profile image
Shubham Tiwari

Yeah, using map is effective and recommend when keys are not guaranteed strings as Map preserve the actual reference of non strings and won't have any key collisions and it will be faster as compared to plain objects

Collapse
 
nevodavid profile image
Nevo David

Been grinding through JavaScript for a while and picking up little stuff like this does make it smoother day to day

Collapse
 
nadeem_zia_257af7e986ffc6 profile image
nadeem zia

Interesting to read

Collapse
 
madiha_rehman profile image
Madiha Malik

Thanks 😊 very helpful 👍

Some comments may only be visible to logged-in visitors. Sign in to view all comments.