First off, here's a post with code that shows how to start to use a plain Javascript object for set-like behavior (with some limitations).
And, here's a set of objects (that work in ES5) for getting lots more set-like behavior.
And, here a partial ES6 polyfill for the Set object implemented in ES5.
If you study any of this code, you will see that a plain Javascript object falls far short of an ES6 Set in many ways that require significant additional coding to work around.
Here are a couple of those issues:
Assigning an object as a key will not work properly because all objects convert to a string key of "[object Object]"
so all objects would have the same key in your set-like Javascript object.
Assigning a number as a key will convert to the string representation so keys like 4
and "4"
will conflict.
The ES6 Set object does not have these limitations. Here's more discussion of these two issues:
If you look at this answer to a prior post and the code in that answer, you can see how an underlying Javascript object can be used as the lookup mechanism for set-like behavior. Without lots of other coding though, it has some limitations because a Javascript object requires a string as the lookup key. An ES6 Set does not. So, out of the box the ES6 Set supports objects as elements. Using a Javascript object as a poor man's set does not support objects as elements in the set.
This becomes the most material when you want to add an object to the plain Javascript object-based set.
// create a set-like object
var mySet = {};
// create an object and put it in the set
var myObj = {greeting: "hello"};
mySet[myObj] = true;
Because a Javascript object requires a string key, it will call myObj.toString()
to get such a key. Without a custom override for the toString()
method, that will come out as "[object Object]" which is not at all what you want. See here for a demo. It will appear to work for one object, but as soon as you have more than one object in the set or set the set for a different object, it won't work at all because all objects would get indexed with the same key.
With an actual ES6 set, on the other hand, it natively accepts and works with objects just fine - you don't have to do anything special.
If you want to see how you can mimic an ES6 set as closely as possible using a plain Javascript object as the lookup mechanism, please read this answer. Further info is located on github where you can see what as to be done to make a regular Javascript object-based set implementation support Javascript objects with this ObjectSet implementation. There's even an ES6 Set polyfill here that uses an underlying Javacript object as it's storage mechanism.
A second issue arises with Javascript object based set implementations which is also because of the string key requirement. If you do this:
var mySet = {};
mySet[4] = true;
mySet["4"] = true;
You will end up with only one item in the set. This is because mySet[4] = true;
converts the 4
to a string "4"
to use as the key. If you are only using strings in your set or only using numbers in the set, then this can be easily worked around, but if you have both strings and numbers in the set, then a javascript object-base set implementation does not distinguish between 4
and "4"
so does not treat them as separate items in the set. An ES6 does make this distinction.
Again, it would be possible to work around this with more code. If you manually do the toString()
conversion yourself to create the key, one can preprend to the key value some type information such that in the above example, the key for the number 4
becomes "num_4"
instead of just "4". To prevent collisions with a string '"num_4"`, you have to also do the same for string types. And numbers aren't the only type with this issue. In fact, in this ES6 Set polyfill, you can see a unique key being generated here. That unique key then has to be regenerated and used to do any lookup in the set.