Skip to main content

How to Increment a Value in an Object or Map in JavaScript

A common task in programming is to keep a running count of items, such as the frequency of words in a text or the number of votes for different options. This often involves incrementing a value associated with a key in an object or a Map. The main challenge is handling the first time you encounter a key, where the value needs to be initialized to 1 instead of being incremented.

This guide will teach you the modern, concise, and robust methods for incrementing values in both plain objects and Map objects, using the nullish coalescing operator (??).

The Core Problem: Initializing vs. Incrementing

When you're counting items, your code must handle two different scenarios for any given key:

  1. If the key does not exist yet: You need to add it to your object or Map and initialize its value to 1.
  2. If the key already exists: You need to retrieve its current value, add 1 to it, and update the value.

A naive if/else block can solve this, but modern JavaScript offers a much more elegant one-liner.

Incrementing a Value in an Object

The most robust and modern way to handle this is with the nullish coalescing operator (??). This operator provides a default value (0) only if the existing value is null or undefined.

For example, you have an object and want to increment the value for a key, or initialize it if it doesn't exist.

// Problem: How to increment 'apples' and initialize 'bananas'?
const fruitCounts = {
apples: 2,
};

Solution:

const fruitCounts = {
apples: 2,
};

// Increment the value for 'apples'
fruitCounts['apples'] = (fruitCounts['apples'] ?? 0) + 1;
console.log(fruitCounts.apples); // Output: 3

// Initialize the value for 'bananas'
fruitCounts['bananas'] = (fruitCounts['bananas'] ?? 0) + 1;
console.log(fruitCounts.bananas); // Output: 1

console.log(fruitCounts); // Output: { apples: 3, bananas: 1 }

How it works:

  • fruitCounts['apples'] ?? 0: The ?? operator checks the value of fruitCounts['apples'].
    • Since it exists and is 2 (which is not null or undefined), the expression evaluates to 2. The line becomes fruitCounts['apples'] = 2 + 1.
  • fruitCounts['bananas'] ?? 0: The ?? operator checks the value of fruitCounts['bananas'].
    • Since it doesn't exist, its value is undefined. The ?? operator then returns the fallback value on the right, 0. The line becomes fruitCounts['bananas'] = 0 + 1.

Incrementing a Value in a Map

The logic is identical for a Map, but you use the .get() and .set() methods.

For example, you have a Map and want to increment a value or initialize it.

// Problem: Increment 'apples' and initialize 'bananas' in a Map.
const fruitMap = new Map([['apples', 2]]);

Solution:

const fruitMap = new Map([['apples', 2]]);

// Increment the value for 'apples'
fruitMap.set('apples', (fruitMap.get('apples') ?? 0) + 1);
console.log(fruitMap.get('apples')); // Output: 3

// Initialize the value for 'bananas'
fruitMap.set('bananas', (fruitMap.get('bananas') ?? 0) + 1);
console.log(fruitMap.get('bananas')); // Output: 1

console.log(fruitMap); // Output: Map(2) { 'apples' => 3, 'bananas' => 1 }

A Common Pitfall: Using the Logical OR (||) Operator

A common but flawed approach is to use the logical OR operator (||) instead of the nullish coalescing operator (??).

Here we have a problem of incorrect logic:

  • The || operator returns the right-hand side if the left-hand side is any falsy value (0, '', false, null, undefined).
  • The number 0 is a valid count, but || will incorrectly treat it as a "missing" value.
// Problem: What happens when a count is 0?
const scores = {
'player1': 0
};

// INCORRECT: Using the || operator
scores['player1'] = scores['player1'] || 0;
scores['player1'] += 1; // This is now 0 + 1

console.log(scores['player1']); // Output: 1 (This seems to work...)

// But what if we try the one-liner?
scores['player1'] = (scores['player1'] || 0) + 1;
// This becomes: scores['player1'] = (0 || 0) + 1 => (0) + 1 => 1
// It works here, but it's a dangerous habit.

const scores2 = { player1: 0 };
scores2['player1'] = scores2['player1'] + 1 || 1;
// This becomes: scores2['player1'] = 0 + 1 || 1 => 1 || 1 => 1
console.log(scores2['player1']); // It still seems to work.
note

The nullish coalescing operator (??) does not have this bug. It only provides the fallback for null or undefined, correctly treating 0 as a valid, existing value.

note

Always use the nullish coalescing operator (??) for this pattern. It is safer and more explicit about what you are trying to achieve.

Conclusion

Incrementing a value in an object or Map is a simple task with modern JavaScript syntax.

  • The recommended best practice is to use the nullish coalescing operator (??) to provide a default value of 0 before adding 1.
    • For objects: obj[key] = (obj[key] ?? 0) + 1;
    • For Maps: myMap.set(key, (myMap.get(key) ?? 0) + 1);
  • Avoid using the logical OR (||) operator for this pattern, as it can lead to bugs by incorrectly handling a count of 0.

This modern approach is concise, readable, and robustly handles both initializing and incrementing values in a single line.