Is it possible to convert a javascript reference to a number or a hash sum?

Let's say you want to compare two javascript objects or arrays for referential equality.

The most obvious solution would be

if (a === b) { /*...*/ };

      

The problem is that a

both b

would have to contain references to the actual objects. This can be a problem in the same cases. For example, trying to store the actual references in the memoization function will create a memory leak.

One approach is to use JSON.stringify(a)

to get string representations of objects and compare them. But this can be prohibitively expensive in some use cases. Not to mention, actual reference equality is not taken into account.

I'm interested. Is there a way to shrink the actual link instead of the object's content? Obviously, you cannot manipulate pointers in javascript, but what if you could only get a representation of a pointer of some kind. Hash sum? A place of raw memory? Guide or integer representation?

I know there are some types of object ids when parsing a memory dump in chrome dev tools. Perhaps these things can be obtained at runtime? Using some kind of custom switch in node.js?

Can anyone think of how to do this in javascript?

+3


source to share


2 answers


If you want to use this for remembering (caching) you must use ES6 WeakMap

. It works on Firefox 6, Chrome 36 and IE 11.

A WeakMap object is a collection of key / value pairs in which keys are objects and values ​​can be arbitrary values. [...] An experienced JavaScript programmer will notice that this API can be implemented in JavaScript with two arrays (one for keys, one for values), separated by four API methods. This implementation will have two main disadvantages. The first is an O (n) lookup (n is the number of keys on the map). The second problem is the problem of memory leaks.



It works like a map in Java - you can use arbitrary objects like keys and values. But keys won't prevent garbage collection, so you don't have to worry about memory leaks, but you can still find memorized computations for a given object.

+3


source


Inspired by @ user2864740's comment (dude, customize the name, seriously :-)).

it can also just be a required method for objects that will participate in this system

This implementation extends the object prototype to include a utility to generate a unique UUID for each object. generateId

the implementation is taken from here .

It seems to work for objects and arrays.



Object.prototype._id = function () {
    return this.__id || (this.__id = generateId());

    function generateId() {
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
            var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        });
    }
}

function assert(message, test) {
    if (!test) {
        throw new Error("ASSERTION FAILED: " + message);
    } else {
        console.log("PASSED: " + message);
    }
}


var x = { name: "same" },
    y = { name: "same" },
    z = [],
    x2 = x;

assert("Id is unchanging", x._id() === x._id());
assert("Id is different  for different objects", x._id() !== y._id());
assert("Arrays have id too", z._id() === z._id());
assert("Id is same for same objects", x._id() === x2._id());

      

Live example

I am leaving this here to see if there are problems or maybe someone has a better idea.

0


source







All Articles