How to get the identity of an object in JavaScript?

9
Several languages have a means of obtaining the "identity" of an object, i.e. a [integer] number that is unique to each object, such that different objects have different identities. Examples:

  

As far as reasonably practical, the hashCode method defined by the Object class returns distinct integers for distinct objects. (This is typically implemented by converting the object's internal address into an integer, but this implementation technique is not required by the Java programming language.)

  • Python ( id )
  

Returns the "identity" of an object. This is an integer (or long integer) that is guaranteed to be unique and constant for this object during its life cycle. Two non-overlapping objects can have the same value for id ().

Is there any similar functionality in JavaScript? Preferably standardized, that works in all browsers and other environments (Rhino, V8). Searching for "identity" I only find references to the operator ( === ) ...

I know that some environments do not support this concept (.NET seems to not for optimization reasons ), but in This is not a problem because they are more complete languages, which have the concepts of destructor , finalizer and / or weak references . As far as I know, JavaScript does not support this, so a way to get a numeric value that uniquely represents an object would be very useful (a simple reference to the object does not help because it would prevent it from being collected as garbage.)

    
asked by anonymous 15.12.2013 / 11:35

2 answers

11

The ECMA-262 specification does not provide this functionality in the language, and I am not aware of any JavaScript engine that implements this.

If you want to deploy yourself, this is a starting point (based on this English response ):

(function(){
    var id = 0;
    Object.prototype.getIdentity = function() {
        if(!this.hasOwnProperty('__identity__')) {
            this.__identity__ = ++id;
        }
        return this.__identity__;
    };
}());

Note that __identity__ is a public property that all objects that invoke getIdentity once have. Therefore nothing prevents it from being manipulated directly, which would potentially compromise the results.

A feature-rich implementation of ECMAScript 5 (ie incompatible with older engines like IE8) can prevent this:

(function(){
    var id = 0;
    Object.prototype.getIdentity = function() {
        if(!this.hasOwnProperty('__identity__')) {
            Object.defineProperty(this, '__identity__', { 
                enumerable: false,
                writable: false,
                value: ++id 
            });
        }
        return this.__identity__;
    };
}());

The writable: false attribute ensures that the __identity__ value can not be changed manually. E enumerable: false omit the property of enumerations for..in , or serialization via JSON.stringify , as suggested by the size.

    
15.12.2013 / 13:06
1

You can add a global functionality for type String :

String.prototype.hashCode = function(){
    var hash = 0;
    for (var i = 0; i < this.length; i++) {
        var character = this.charCodeAt(i);
        hash = ((hash << 5) - hash) + character;
        hash = hash & hash; // Converte para inteiro 32 bit
    }
    return hash;
}

Font

The Lo-Dash library offers some useful features. One of them is the possibility to compare the equivalence of two values

link

var object = { 'name': 'fred' };
var copy = { 'name': 'fred' };

object == copy;
// → false

_.isEqual(object, copy);
// → true

var words = ['hello', 'goodbye'];
var otherWords = ['hi', 'goodbye'];

_.isEqual(words, otherWords, function(a, b) {
  var reGreet = /^(?:hello|hi)$/i,
      aGreet = _.isString(a) &amp;&amp; reGreet.test(a),
      bGreet = _.isString(b) &amp;&amp; reGreet.test(b);

  return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
});
// → true
    
15.12.2013 / 12:32