close icon
daily.dev platform

Discover more from daily.dev

Personalized news feed, dev communities and search, much better than what’s out there. Maybe ;)

Start reading - Free forever
Start reading - Free forever
Continue reading >

Modern JavaScript Essentials for Developers

Modern JavaScript Essentials for Developers
Author
Nimrod Kramer
Related tags on daily.dev
toc
Table of contents
arrow-down

🎯

Explore the essentials of modern JavaScript development including arrow functions, promises, async/await, and modules. Enhance your coding skills with these key concepts!

If you're looking to get up to speed with modern JavaScript, here's a quick rundown of essential concepts and features every developer should know:

  • Arrow Functions: A concise way to write functions. They keep this context and eliminate the need for the word 'return' in single expressions.
  • Promises: Enable handling asynchronous operations more straightforwardly, allowing you to perform actions in sequence or catch errors neatly.
  • Async/Await: Simplify working with Promises, making your asynchronous code look and behave like synchronous code.
  • Modules: Help organize code by splitting it into reusable pieces, which can be exported from one file and imported into another for a cleaner, more modular structure.

These concepts form the backbone of modern JavaScript development, streamlining code and making development more intuitive. Whether you're beginning your journey with JavaScript or looking to refresh your knowledge, understanding these key areas will greatly enhance your coding projects.

ECMAScript Versions

As time goes by, new versions of ECMAScript come out, bringing in cool new things to JavaScript:

  • ES5 (2009) - Brought in handy methods like Array.prototype.forEach and Object.keys
  • ES6/ES2015 (2015) - Introduced stuff like classes, arrow functions, and promises.
  • ES2016-ES2022 (2016-2022) - Added even more, like async/await, optional chaining, and nullish coalescing.

With every new version, JavaScript gets more features that make it better and more versatile.

Transpiling and Polyfilling

New ECMAScript features aren't always immediately available in all web browsers or platforms. That's where transpiling and polyfilling come in:

  • Transpilers like Babel change new ECMAScript stuff into an older version that more browsers understand.
  • Polyfills let us use new features by mimicking them with older code, so we don't have to wait for browsers to catch up.

By using transpilers and polyfills, developers can write code using the latest JavaScript features without worrying about whether they'll work everywhere. This makes it easier to keep websites and apps up-to-date with new programming capabilities.

Arrow Functions

Arrow functions are a simpler way to write functions in JavaScript. Here's why they're cool:

They're shorter

Old way:

function(a){
  return a + 100; 
}

New, shorter way with arrow functions:

a => a + 100

They're smart with this

With arrow functions, this doesn't change its meaning inside different parts of the function. This makes things less confusing:

const obj = {
  id: 42,
  getId: () => {
    return this.id;
  }
}

obj.getId(); // 42

They can skip the word 'return'

If the function does just one thing, you don't have to write 'return':

const double = (x) => x * 2; 

double(7); // 14

When to use them

Arrow functions are great for:

  • Quick functions:
[1, 2, 3].map(x => x * 2); 
  • When something happens (like clicking a button):
button.addEventListener('click', () => {
  // what to do when clicked
});
  • Keeping this in check inside class methods:
class MyClass {
  method = () => {
    // 'this' is still the MyClass instance
  }
}

In short, arrow functions make writing JavaScript easier by keeping things short and making this less tricky to deal with. They're especially handy for quick functions, handling events, and dealing with this in class methods.

Promises

Promises are like a pinky promise in JavaScript for doing things that take time, like getting info from the internet. They let you do other stuff while waiting for that slow task to finish.

Creating Promises

To make a promise, you use the Promise constructor like this:

const myPromise = new Promise((resolve, reject) => {
  // do async stuff
  if (success) {
    resolve(value); 
  } else {
    reject("failure reason");
  }
});

Here, you tell the promise what to do if it works out (resolve) and what to do if it doesn’t (reject).

Consuming Promises

To use a promise, you add .then() for when things go right and .catch() for when they don’t:

myPromise
  .then((result) => {
    // handle success 
  })
  .catch((error) => {
    // handle failure  
  });

This way is much cleaner than having lots of callbacks!

Promise Chaining

You can link promises together with .then() so one starts after the previous one finishes:

functionA()
  .then((result) => functionB(result)) 
  .then((newResult) => functionC(newResult));

If something goes wrong, the error will move down the chain until it’s caught.

Avoiding Callback Hell

Instead of a scary ladder of callbacks like this:

async1(function(value1) {
  async2(function(value2) {
    async3(function(value3) {
      // etc...
    });
  });
});

You can write this way using promises:

async1()
  .then((value1) => {
    return async2();  
  })
  .then((value2) => {
    return async3();
  }) 
  // etc

It’s way easier to follow!

In a nutshell, promises make dealing with waiting around for things in JavaScript a lot smoother. They keep your code neat and make it easier to see what’s happening.

sbb-itb-bfaad5b

Async/Await

Async/await in JavaScript is like a magic trick for making code that waits on things (like fetching data from the internet) look and act more like regular, straightforward code. It helps you avoid getting stuck in a maze of callbacks or getting lost in a bunch of .then() and .catch() when working with promises.

Here's a simple breakdown:

  • async before a function means it can automatically wait for stuff without blocking other code from running.
  • await is used inside those async functions and it pauses the code there until the thing you're waiting on is done. But, it only makes the async function wait, not your whole program.
  • If something goes wrong in an async function, it's like the function says "I can't keep my promise" and it sends back an error.

Let's look at an example using promises first:

function getUser() {
  return fetch('/api/user'); 
}

function getPosts(user) {
  return fetch('/api/posts?user=' + user.id);
}

getUser()
  .then(user => getPosts(user))
  .then(posts => {
    // show posts
  })
  .catch(error => {
    // handle error  
  });

And now, let's rewrite that with async/await:

async function showPosts() {
  try {
    const user = await getUser();
    const posts = await getPosts(user);
    
    // show posts 
  } catch (error) {
    // deal with error
  }
}

showPosts();

See? Much cleaner! The code flows like a story, even though it's doing waiting in between steps.

Important things to remember about async/await:

  • You can handle errors with try/catch, which is like saying "I'm going to try this, but if it messes up, I'll catch the problem here."
  • await only works in functions that are marked with async.
  • Your code after an await will wait its turn until the awaited thing is finished.

In short, async/await lets you write code that waits on stuff in a way that's easy to read and understand. It's great for avoiding complicated code paths and makes handling errors a breeze.

Modules

Modules are like little boxes where you can keep parts of your JavaScript code separate from each other. This is great for when you want to keep your code tidy and easy to understand.

Exporting and Importing

When you want to use code from one file in another, you can share it. You do this by exporting code from the first file and importing it into the second.

Here's how you can share some math functions between files:

math.js

export function add(a, b) {
  return a + b;
}

export function multiply(a, b) {
  return a * b; 
}

To use these in another file, do this:

import {add, multiply} from './math.js';

add(1, 2); // 3
multiply(3, 4); // 12

The {} lets you choose exactly what you want to bring over.

Default Exports

Sometimes, you might want to have a main thing that gets used by default if you don't specify anything else:

math.js

export default function subtract(a, b) {
  return a - b;
}

index.js

import subtract from './math.js';

subtract(5, 3); // 2

Bundling

Tools like Webpack help put all your modules together into a few files that browsers can load quickly. They help by:

  • Making sure modern code works on all devices
  • Keeping imports/exports working together nicely
  • Letting you see changes to your code right away as you work

Bundling makes using modules easy without slowing things down.

In short, JavaScript modules let you split your code into manageable parts. Sharing code between files is straightforward with exporting and importing. Bundlers make sure everything works smoothly together, so your website or app runs fast. This setup helps you write better JavaScript code that's easier to handle.

Conclusion

The latest updates to JavaScript bring a bunch of cool tools that make coding simpler and your code neater. If you're getting into JavaScript or already have some experience, it's really important to get the hang of features like arrow functions, promises, async/await, and modules.

Here's a quick look back at what we talked about:

  • Arrow functions are a shorter way to write functions, they're smart with how they handle this, and you don't always have to use return when the function is just one line. They're great for when you need to do something after a click or when working with class methods.
  • Promises help you deal with actions that take time, like getting data from the internet, without getting stuck in a mess of callbacks. You can line them up one after another with .then() and catch any errors with .catch().
  • Async/await lets your code wait for these time-consuming actions without freezing everything else. It makes your code look cleaner and more like a straight line, which is easier to follow.
  • Modules let you keep different parts of your code in separate files, which makes everything more organized. You can share code between files with export and import. Tools like Webpack help bundle everything together so it runs smoothly and quickly.

With these key ideas, you'll be all set to tackle modern JavaScript and really make the most of what the language offers today. Keep exploring resources like MDN and the official docs to keep growing your skills.

Related posts

Why not level up your reading with

Stay up-to-date with the latest developer news every time you open a new tab.

Read more