(kind of) Getting the memory address of a JavaScript object
Tags: javascript, address, memory, map
Published: 2019-11-28 22:35:36

Hey everyone,

I am building a library for [Graph Object Notation](https://github.com/MakeItHappenDev/GraphObjectNotation), at the moment in super early stage, and I came across a really nice "loophole" to what I imagined being the biggest obstacle of the project : __Getting the memory address of the objects in JavaScript__. [Here is a nice post if you need a quick reminder on how memory works in JavaScript!](https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0)

As you may know, you can't access them for security reasons, end of the post, thank you for reading...
...but turns out, you can cheat a little bit there. The actual address isn't really that important in my case, what's important is the consistency of the "fake address" that we will generate and make sure the same object always spits out the same address!

First though is to go on and brute force things, building an array of known Object, another of fake address and comparing every object against that array. Turns out it works, but here comes the slow library judgement.
Second though, building hashes of the object based on properties and values, then only comparing with "same hash" object, works as well, but not really efficient either.

Then came an idea.

The __Map object__ isn't really used in the JavaScript front-end world, but it's really effective at finding if it has a key defined, and it can hold any type of data as a key. This is contrary to the Object object, where keys can only be strings. 

__1 + 1 = success, let's use the objects themselves as key, and the fake address as value.__

Here is a short video on how it works : https://youtu.be/-ZenKpRfJdo


And the next one in a more functional programming style, with a nice triple arrow function : https://youtu.be/r7y8roTIPig

And for those not wanting to watch a video, here's the code : 
(the live version is here)[https://gon.arthurj.now.sh/references]


https://codesandbox.io/s/vibrant-northcutt-wkh2e

```js
const user1 = { name: "arthur" };
const users = [user1, { name: "arthur" }, { name: "Joe" }, user1];

//This generator doesn't garantee uniqueness, but looks way more memoryish than a incremental counter
//if you use this code for real, do incremental or something else unique!
function* generator() {
  while (true) {
    const random = Math.random()
      .toString(16)
      .slice(2, 10);
    yield `0x${random}`;
  }
}

const preload = (knowObjects, refs, generate) => (reference = false) => {
  if (reference) {
    return refs;
  } else {
    return object => {
      let address;
      if (knowObjects.has(object)) {
        address = knowObjects.get(object);
      } else {
        address = generate.next().value;
        knowObjects.set(object, address);
        refs[address] = object;
      }
      return address;
    };
  }
};

const setup = preload(new Map(), {}, generator());
const findRef = setup(false);

const array = users.map(u => findRef(u));
/*
console.log something like that, and builds up the knowObjects map / refs object
[
 "0xf094c649",
 "0x7de35306",
 "0x6a99aa2f",
 "0xf094c649"
]
*/

const refs = setup(true);
/*
console.log something like this
{
 "0xf094c649": {
  "name": "arthur"
 },
 "0x7de35306": {
  "name": "arthur"
 },
 "0x6a99aa2f": {
  "name": "Joe"
 }
}
*/
```