Using Object Literals Instead of Switch Statements in JavaScript

Using Object Literals Instead of Switch Statements in JavaScript

I often struggle to remember the syntax of JavaScript's switch statement. However, I am grateful for VS Code's autocomplete option. The switch statement is strange in terms of syntax because it is the only element that doesn't use curly brackets and requires a break statement for each case. It also performs poorly due to its procedural control flow.

A better alternative for most switch statement cases is JavaScript's object literals. This technique involves creating an object with a key for each case that would normally be handled by the switch statement. By using the provided phrase as the key, you can directly access the corresponding value.

// Original switch statement
let animal = 'cats';

switch (animal) {
  case 'dogs':
    console.log('Dogs');
    break;
  case 'cats':
    console.log('Cats');
    break;
  case 'birds':
    console.log('Birds');
    break;
}
// Output: 'Cats'

// Improved approach using object literals
const animalActions = {
  'dogs': () => console.log('Dogs'),
  'cats': () => console.log('Cats'),
  'birds': () => console.log('Birds')
};

// Call the appropriate function based on the animal
animalActions[animal](); // Output: 'Cats'        

Using object literals is not only clearer and shorter, but it also runs much faster. However, we still need to address the default case. To handle this, simply add a 'default' key and check if the expression's value exists in the object.

let vehicle = 'motorcycle';

switch (vehicle) {
  case 'car':
    console.log('Car');
    break;
  case 'bike':
    console.log('Bike');
    break;
  default:
    console.log('Unknown vehicle');
}
// Logs: 'Unknown vehicle'

const logVehicle = {
  'car': () => console.log('Car'),
  'bike': () => console.log('Bike'),
  'default': () => console.log('Unknown vehicle')
};

(logVehicle[vehicle] || logVehicle['default'])(); // Logs: 'Unknown vehicle'        

Additionally, our object literal replacement should be able to handle falling through scenarios, just like when there is no break statement. This can be achieved by copying code from the object literal.

let color = 'blue';

switch (color) {
  case 'red':
  case 'blue':
    console.log('Known color');
    break;
  default:
    console.log('Unknown color');
}
// Logs: 'Known color'

const knownColor = () => console.log('Known color');
const unknownColor = () => console.log('Unknown color');

const logColor = {
  'red': knownColor,
  'blue': knownColor,
  'default': unknownColor
};

(logColor[color] || logColor['default'])(); // Logs: 'Known color'        

In summary, we can create a simple and reusable function to generalize and extract this logic. This function will take the lookup object and an optional name for the _default scenario. It will generate a function that contains the necessary lookup logic, which can be used to replace any switch statement.

const switchFn = (lookupObject, defaultCase = '_default') =>
  expression => (lookupObject[expression] || lookupObject[defaultCase])();

const knownAnimal = () => console.log('Known animal');
const unknownAnimal = () => console.log('Unknown animal');

const logAnimal = {
  'dogs': knownAnimal,
  'cats': knownAnimal,
  'default': unknownAnimal
};

const animalSwitch = switchFn(logAnimal, 'default');

animalSwitch('dogs'); // Logs: 'Known animal'
animalSwitch('hamsters'); // Logs: 'Unknown animal'
        

要查看或添加评论,请登录

Shantun Parmar的更多文章

社区洞察

其他会员也浏览了