jsguides

Set.prototype.size

set.size

The size property returns the number of unique elements in a Set. It provides a constant-time way to determine how many distinct values the Set contains.

Syntax

set.size

Description

The size property is a getter that returns an integer representing the cardinality — the count of unique elements stored in the Set. Unlike arrays, Sets automatically eliminate duplicates, so size always reflects the actual number of distinct values.

Key Characteristics

  • Read-only: size is a getter property, not a method. It cannot be set directly.
  • Constant-time: Accessing size is O(1), regardless of how many elements are in the Set.
  • Auto-updating: The value updates automatically when elements are added or removed.
  • Empty sets return 0: A Set with no elements has a size of 0.

Examples

Basic usage: check element count

const fruits = new Set(['apple', 'banana', 'apple', 'orange', 'banana']);

console.log(fruits.size);
// 3 (duplicates are ignored)

Duplicates are silently discarded during construction, so size gives you the true count of distinct values right away. The same principle applies when the Set is empty: size returns 0 rather than undefined or an error, which makes guard clauses straightforward.

Empty set returns zero

const emptySet = new Set();

console.log(emptySet.size);
// 0

// Checking size before processing prevents unnecessary operations
if (emptySet.size > 0) {
  console.log('Processing items...');
} else {
  console.log('No items to process');
}
// No items to process

While size always reports unique elements, the equivalent array property length counts duplicates. Comparing the two is instructive because it highlights the semantic difference: one counts what was inserted, the other counts what is distinct. The example below makes this concrete by building a Set and an array from the same data.

Comparing with Array.length

Arrays and Sets handle duplicates differently:

// Array: length includes duplicates
const array = [1, 2, 2, 3, 3, 3];
console.log(array.length);
// 6

// Set: size counts unique elements only
const set = new Set([1, 2, 2, 3, 3, 3]);
console.log(set.size);
// 3

// Adding more duplicates has no effect on Set size
set.add(2);
set.add(3);
console.log(set.size);
// Still 3

Knowing how size differs from length is useful, but the property really shines in decision-making code. The next example uses size to gate access logic and to drive a logging message, combining a quick emptiness check with a human-readable count.

Practical: check before processing

const userPermissions = new Set();

// Add some permissions
userPermissions.add('read');
userPermissions.add('write');

function checkAccess(requiredPermission) {
  // Quick size check for logging
  console.log(`Checking access. Total permissions: ${userPermissions.size}`);
  
  if (userPermissions.size === 0) {
    return 'No permissions configured';
  }
  
  return userPermissions.has(requiredPermission) ? 'Granted' : 'Denied';
}

console.log(checkAccess('read'));
// Checking access. Total permissions: 2
// Granted

console.log(checkAccess('delete'));
// Checking access. Total permissions: 2
// Denied

Size vs Length

AspectSetsizeArraylength
TypeGetter propertyProperty (writable)
DuplicatesCounts unique onlyCounts all elements
SettableNoYes (arr.length = 5)
Always accurateYesYes

Common Patterns

Guard Clauses

function processSetData(dataSet) {
  // Early return for empty set
  if (dataSet.size === 0) {
    return [];
  }
  
  // Process only if set has data
  return [...dataSet].map(x => x.toUpperCase());
}

A guard clause with size keeps the function’s main logic from ever running against an empty collection, which avoids downstream errors and unnecessary work. The same size check can also gate side effects like database writes — if nothing changed, skip the round trip.

Conditional Processing

const tags = new Set(['javascript', 'es6', 'javascript']);

// Only save if we have unique tags
if (tags.size > 0) {
  saveToDatabase([...tags]);
}

size is a getter, not a method

size is a getter property, not a method — you access it as set.size, not set.size(). Calling set.size() throws TypeError: set.size is not a function. The same is true for Map.prototype.size. This differs from Array.prototype.length, which is a plain property (not a getter), though the access syntax looks the same.

Counting unique values

size is commonly used to count unique values in a collection:

const ids = [1, 2, 3, 2, 1, 4];
const uniqueCount = new Set(ids).size; // 4

const text = "abracadabra";
const uniqueChars = new Set(text).size; // 5 (a, b, r, c, d)

This pattern — create a Set, read size, discard the Set — is more concise than sorting and deduplicating manually, and it runs in O(n) time.

size vs Map.prototype.size

Both Set.prototype.size and Map.prototype.size behave identically: O(1) access, read-only, automatically updated when entries are added or removed. Neither can be assigned directly — attempting set.size = 10 silently fails in non-strict mode and throws in strict mode. Use clear(), add(), or delete() to change the count.

Why size Matters

size is the quickest way to tell whether a Set is empty and how much unique data it currently holds. That makes it useful for guard clauses, logging, and user-interface states that depend on whether the collection has anything worth processing. Because it updates automatically, you do not need to keep a second counter in sync, which removes a whole class of bookkeeping bugs.

See Also