DEV Community

Cover image for JavaScript Object Literals: The Secret Weapon for Simpler Code
João Antunes
João Antunes

Posted on

JavaScript Object Literals: The Secret Weapon for Simpler Code

Recently, I came across a problem:
I had a list of events and needed to create a function that could take an event as a parameter and determine which corresponding function should be executed.

To represent the events, I used an object where each key corresponds to an event and each value represents its identifier.

The challenge was to make the handleEvents function identify the received event and call its corresponding function.

Challenge Code:

const eventList = {
  Event1: 'AV1',
  Event2: 'BV2',
  Event3: 'CV3',
  Event4: 'DV4',
  Event5: 'EV5',
}

function executeEvent1() {
  // execute event 1
}

function executeEvent2() {
  // execute event 2
}

function executeEvent3() {
  // execute event 3
}

function executeEvent4() {
  // execute event 4
}

function executeEvent5() {
  // execute event 5
}

function handleEvents(key) {
  // need implementation...
}

handleEvents("AV1");
Enter fullscreen mode Exit fullscreen mode

Looking at this problem, we might imagine a solution using if or switch conditionals, but the list of events could grow as the project progresses, so I felt the need for a better implementation, rather than the code looking like this,

Problematic Code:

const eventList = {
  Event1: 'AV1',
  Event2: 'BV2',
  Event3: 'CV3',
  Event4: 'DV4',
  Event5: 'EV5',
};

function handleEvents(key) {
  // using if conditionals...
  if (key === eventList.Event1) {
    executeEvent1();
  } else if (key === eventList.Event2) {
    executeEvent2();
  } else if (key === eventList.Event3) {
    executeEvent3();
  } else if (key === eventList.Event4) {
    executeEvent4();
  } else if (key === eventList.Event5) {
    executeEvent5();
  }
}

handleEvents("AV1");
Enter fullscreen mode Exit fullscreen mode

Following the above model, as more events were added to the list, the code would become larger and less readable, making maintenance and understanding more difficult. It would also affect the scalability of the code, since each new event would require the creation of a new function and more conditional checks.

Given this scenario, how can we make the code more readable and easier to maintain?

The solution I found was to use Object Literals, an approach that improves the organization of the code and simplifies the execution of the handleEvents function. With that, I arrived at the following implementation:

Object Literals Code:

const eventList = {
  Event1: 'AV1',
  Event2: 'BV2',
  Event3: 'CV3',
  Event4: 'DV4',
  Event5: 'EV5',
}

function handleEvents(key) {
  const eventHandlers = {
    [eventList.Event1]: executeEvent1, 
    [eventList.Event2]: executeEvent2,
    [eventList.Event3]: executeEvent3,
    [eventList.Event4]: executeEvent4,
    [eventList.Event5]: executeEvent5,
  }

  const eventHandler = eventHandlers[key];
  if (eventHandler) {
    eventHandler();
  }
}

handleEvents("AV1");
Enter fullscreen mode Exit fullscreen mode

This way, even if the event list grows in the future, the maintenance and scalability of the code will become more efficient, and it will be much more readable.


Extra Problem

Now, imagine a new scenario: the handleEvents function receives an event and a payload. How would the function calls be handled if the events required parameters for execution?

Object Literals With Parameters:

const eventList = {
  Event1: 'AV1',
  Event2: 'BV2',
  Event3: 'CV3',
  Event4: 'DV4',
  Event5: 'EV5',
};

function handleEvents(key, param) {
  const eventHandlers = {
    [eventList.Event1]: (param) => executeEvent1(param),
    [eventList.Event2]: (param) => executeEvent2(param),
    [eventList.Event3]: (param) => executeEvent3(param),
    [eventList.Event4]: (param) => executeEvent4(param),
    [eventList.Event5]: (param) => executeEvent5(param),
  };

  const eventHandler = eventHandlers[key]; 
  if (eventHandler) {
    eventHandler(param); 
  }
}

handleEvents("AV1", { payload: "data" });
Enter fullscreen mode Exit fullscreen mode

Why Use Arrow Functions in Object Literals?

In the example above, you might wonder why we use arrow functions like this:

[eventList.Event1]: (param) => executeEvent1(param),
Enter fullscreen mode Exit fullscreen mode

Arrow functions are used in object literals to ensure event handlers can dynamically receive parameters. If you directly call a function like executeEvent1(param) inside the object, it would just reference the function without passing the parameter correctly when the event is triggered.

By using an arrow function, such as (param) => executeEvent1(param), we ensure that the parameter is passed dynamically, allowing for flexible and maintainable code. Without arrow functions, the handlers wouldn’t properly handle parameters, making the code less scalable and harder to maintain.


So, what do you think? Do you agree with this solution?
Feel free to leave a comment.

Thanks for your time 😁!

Top comments (0)