How to Check if an Object is a Map or a Set in JavaScript


Welcome, fellow coders! In this blog, we’ll see how to check if an Object is a Map or a Set in JS. Shall we?


Checking for a Map

Method 1: Checking for a Map

The instanceof operator checks if an object is an instance of a particular constructor function. In the case of Maps, it verifies if the object is an instance of the native Map constructor.

JavaScript
const myMap = new Map();

if (myMap instanceof Map) {
  console.log("It's a Map!"); // Output: It's a Map!
}

Explanation:

  • Behind the scenes, instanceof examines the prototype chain. It checks if the prototype property of the constructor appears anywhere in the prototype chain of the object.
  • For Maps, the prototype property of the Map constructor is checked against the prototype chain of myMap.
  • If myMap is indeed an instance of Map, the condition evaluates to true.

⚠ Common Gotcha:

Extending the Map class can lead to unexpected results. When extending, the instanceof check might yield true for both the parent and child classes.

JavaScript
class CustomMap extends Map {}

const myCustomMap = new CustomMap();

if (myCustomMap instanceof Map) {
  console.log("It's a Map!"); // Output: It's a Map!
} else {
  console.log("Oops, it's not a Map!"); // This might be unexpected
}

In this example, even though myCustomMap is an instance of CustomMap, the instanceof check incorrectly evaluates to true for both CustomMap and Map.

Method 2: Duck Typing – If It Quacks Like a Map 🦆

Duck typing involves checking for the presence of specific properties or methods rather than a direct object type. For Maps, we can check if the object has essential Map methods.

JavaScript
function isMap(map) {
  if (
    map &&
    typeof map.clear === 'function' &&
    typeof map.delete === 'function' &&
    typeof map.get === 'function' &&
    typeof map.has === 'function' &&
    typeof map.set === 'function'
  ) {
    return true;
  }

  return false;
}

// Class duck typed on Map
const duckMap= {
  clear: () => {},
  delete: () => {},
  get: () => {},
  has: () => {},
  set: () => {},
};

console.log(isMap(duckMap)); // Output: true

Explanation:

  • The isMap function checks for existence essential map methods like: set, clear, delete, get, and has.
  • This guards against false positives that might arise from objects with methods having the same name but differing in functionality.
  • This approach focuses on the behavior of the object rather than its class.

⚠ Common Gotchas:

Duck typing can produce false positives if an object has the same methods as a Map but isn’t a Map. Carefully consider the specific methods needed for accurate identification.

⚠ False Positives
JavaScript
function isMap(obj) {
  return typeof obj === 'object' && typeof obj.set === 'function';
}

const fakeMap = { set: () => console.log("Fake set method") };

console.log(isMap(fakeMap)); // Output: true (Uh-oh!)

Here, fakeMap has a set method, tricking the duck typing check into classifying it as a Map, leading to a false positive.

⚠ Insufficient Checks
JavaScript
function isMap(map) {
  if (
    map &&
    typeof map.clear === 'function' &&
    typeof map.delete === 'function' &&
    typeof map.get === 'function' &&
    typeof map.set === 'function'
  ) {
    return true;
  }

  return false;
}

const notQuiteMap = {
  clear: () => console.log("Clearing something"),
  delete: () => console.log("Deleting something"),
  set: () => console.log("Setting something"),
};

console.log(isMap(notQuiteMap)); // Output: true (But it's not a Map!)

In this example, the isMap function checks for the presence of the clear, delete, get, and set methods to determine if an object behaves like a Map. However, this check is insufficient because it overlooks the critical has method, which is fundamental to Map behavior.


Checking for a Set

Method 1: Using instanceof

Similar to checking for a Map, instanceof verifies if the object is an instance of the native Set constructor.

JavaScript
const mySet = new Set();

if (mySet instanceof Set) {
  console.log("It's a Set!"); // Output: It's a Set!
}

Explanation:

  • The instanceof operator performs a prototype chain check, ensuring that the prototype property of the Set constructor is present in the prototype chain of mySet.
  • If mySet is indeed an instance of Set, the condition evaluates to true.

⚠ Common Gotcha:

Similar to the Map example, if you extend the Set class, the instanceof check may incorrectly evaluate to true for both the extended class and the Set class, leading to unexpected results.

JavaScript
class CustomSet extends Set {}

const myCustomSet = new CustomSet();

if (myCustomSet instanceof Set) {
  console.log("It's a Set!"); // Output: It's a Set!
} else {
  console.log("Oops, it's not a Set!"); // This might be unexpected
}

Method 2: Duck Typing – If It Quacks Like a Set 🦆

Duck typing involves checking for the presence of specific properties or methods rather than a direct object type. For Sets, we can check if the object has essential Set methods.

JavaScript
function isSet(set) {
  if (
    set &&
    typeof set.add === 'function' &&
    typeof set.clear === 'function' &&
    typeof set.delete === 'function' &&
    typeof set.has === 'function'
  ) {
    return true;
  }

  return false;
}

const duckSet= {
  add: () => {},
  clear: () => {},
  delete: () => {},
  has: () => {},
};

console.log(isSet(duckSet)); // Output: true

Explanation:

  • The isSet function checks for existence essential map methods like: add, clear, delete, and has.
  • This guards against false positives that might arise from objects with methods having the same name but differing in functionality.
  • This approach focuses on the behavior of the object rather than its class.

⚠ Common Gotchas:

Duck typing can produce false positives if an object has the same methods as a Set but isn’t a Set. Carefully consider the specific methods needed for accurate identification.

⚠ False Positives
JavaScript
function isSet(obj) {
  return (
    obj &&
    typeof obj.add === 'function' &&
    typeof obj.clear === 'function' &&
    typeof obj.delete === 'function' &&
    typeof obj.has === 'function'
  );
}

const fakeSet = { add: () => console.log("Fake add method") };

console.log(isSet(fakeSet)); // Output: true (Uh-oh!)

Just like the Map example, duck typing may lead to false positives if an object has methods with the same names as Set methods but lacks the expected functionality.

⚠ Insufficient Checks
JavaScript
function isSet(obj) {
  return (
    obj &&
    typeof obj.add === 'function' &&
    typeof obj.clear === 'function' &&
    typeof obj.delete === 'function'
  );
}

const notQuiteSet = { add: () => console.log("Adding something") };

console.log(isSet(notQuiteSet)); // Output: true (But it's not a Set!)

Insufficient duck typing checks may result in false positives, as demonstrated here. The object lacks the has method, yet it passes the check.


🧪Practice Coding Problem: The Cartographer’s Dilemma

In the spirit of Test Driven Development ( 😁), lets test our understanding by solving a problem.

Your task is to implement a function named cartographersDilemma that takes an object (collection) as a parameter and solves the Cartographer’s Dilemma by determining whether it represents a Map, a Set, or neither. The function should return a string indicating the type of the collection.

JavaScript
/**
 * Solve the Cartographer's Dilemma by identifying the type of collection (Map, Set, or Neither).
 * @param {Object} collection - The collection to identify.
 * @returns {string} - The type of collection ('Map', 'Set', or 'Neither').
 */
function cartographersDilemma(collection) {
  // > > > 👉 Write code here 👈 < < < 
}

// Test Cases
const mapInstance = new Map();
console.log(cartographersDilemma(mapInstance)); // Output: 'Map'

const setInstance = new Set();
console.log(cartographersDilemma(setInstance)); // Output: 'Set'

const plainObject = { key: 'value' };
console.log(cartographersDilemma(plainObject)); // Output: 'Neither'
Please attempt before seeing the Answer:
JavaScript
function cartographersDilemma(collection) {
  if (collection instanceof Map) {
    return 'Map';
  } else if (collection instanceof Set) {
    return 'Set';
  } else {
    return 'Neither';
  }
}

Explanation:

  • The cartographersDilemma function uses the instanceof operator to check whether the collection is an instance of the Map or Set constructor.
  • If collection is an instance of Map, it returns ‘Map’. If it’s an instance of Set, it returns ‘Set’.
  • If collection is not an instance of either Map or Set, the function returns ‘Neither’.
  • Test cases in question, demonstrate the usage of the function with instances of Map, Set, and a plain object.

Now you can easily discern Maps and Sets objects in Javascript. And whether you use instanceof or duck typing, you are now aware of the edge cases involved too.

Keep coding 🚀!

Scroll to Top