Based on my understanding of the docs (here and here) one would need a reference to the memory address for it to work:
const foo = {};
const map = new Map();
map.set(foo,'123'); // Can only be done if memory address of `foo` is known. Any other shimming would require stringification of foo
This is because JavaScript object {}
keys can only be strings (at least in ES5).
Yet I see Map
shim being available : https://github.com/zloirock/core-js#map. I tried reading the source but its too neatly abstracted (internally uses strong collection which then imports 10 more files)
Answer any of the following please
foo
to store some string on it and then uses that as the key?Provides compatibility shims so that legacy JavaScript engines behave as closely as possible to ECMAScript 6 (Harmony).
map( ) comes in- it does not mutate the original array. Instead within the map method-it assigns a new empty array(under the hood) and returns this new array, once the evaluation of the callbacks are done on each of the elements in the original array(don't worry if this doesn't make sense…
There are two ways that come to mind. First, obviously, you can have an array of keys, and search it linearly:
Map1 = {
keys: [],
values: [],
};
Map1.set = function(key, val) {
var k = this.keys.indexOf(key);
if(k < 0)
this.keys[k = this.keys.length] = key;
this.values[k] = val;
};
Map1.get = function(key) {
return this.values[this.keys.indexOf(key)];
};
foo = {};
bar = {};
Map1.set(foo, 'xxx');
Map1.set(bar, 'yyy');
document.write(Map1.get(foo) + Map1.get(bar) + "<br>")
The second option is to add a special "key" marker to an object which is used as a key:
Map2 = {
uid: 0,
values: {}
};
Map2.set = function(key, val) {
key = typeof key === 'object'
? (key.__uid = key.__uid || ++this.uid)
: String(key);
this.values[key] = val;
};
Map2.get = function(key) {
key = typeof key === 'object'
? key.__uid
: String(key);
return this.values[key];
};
foo = {};
bar = {};
Map2.set(foo, 'xxx');
Map2.set(bar, 'yyy');
document.write(Map2.get(foo) + Map2.get(bar) + "<br>")
Unlike the 1st option, the second one is O(1). It can be done more accurately by making uid
non-writable/enumerable. Also, each Map
should have its own "uid" name (this can be easily set up in the Map constructor).
The trick is to store in an array and perform the lookup in O(n) time by iterating and using strict comparison—instead of using a true hash function which would be O(1) lookup. For example consider this:
var myObj = {};
var someArray = [{}, {}, myObj, {}];
console.log(someArray.indexOf(myObj)); // returns 2
Here is my implementation from another answer: Javascript HashTable use Object key
function Map() {
var keys = [], values = [];
return {
put: function (key, value) {
var index = keys.indexOf(key);
if(index == -1) {
keys.push(key);
values.push(value);
}
else {
values[index] = value;
}
},
get: function (key) {
return values[keys.indexOf(key)];
}
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With