Идентификатор Объекта JavaScript


У объектов/переменных JavaScript есть какой-то уникальный идентификатор? Как у Руби object_id. Я не имею в виду атрибут DOM id, а скорее какой-то адрес памяти.

4 61

4 ответа:

нет, объекты не имеют встроенного идентификатора, хотя вы можете добавить его, изменив прототип объекта. Вот пример того, как вы можете это сделать:

(function() {
    var id = 0;

    function generateId() { return id++; };

    Object.prototype.id = function() {
        var newId = generateId();

        this.id = function() { return newId; };

        return newId;
    };
})();
touch функция, как предложили другие.

Если вы хотите найти/связать объект с уникальным идентификатором без изменения базового объекта, вы можете использовать WeakMap:

// Note that object must be an object or array,
// NOT a primitive value like string, number, etc.
var objIdMap=new WeakMap, objectCount = 0;
function objectId(object){
  if (!objIdMap.has(object)) objIdMap.set(object,++objectCount);
  return objIdMap.get(object);
}

var o1={}, o2={}, o3={a:1}, o4={a:1};
console.log( objectId(o1) ) // 1
console.log( objectId(o2) ) // 2
console.log( objectId(o1) ) // 1
console.log( objectId(o3) ) // 3
console.log( objectId(o4) ) // 4
console.log( objectId(o3) ) // 3

С помощью WeakMap гарантирует, что объекты все еще могут быть собраны в мусор.

на самом деле, вам не надо изменять object прототип. Следующие должны работать, чтобы получить уникальные идентификаторы для любого объекта, достаточно эффективно.

var __next_objid=1;
function objectId(obj) {
    if (obj==null) return null;
    if (obj.__obj_id==null) obj.__obj_id=__next_objid++;
    return obj.__obj_id;
}

Я только что наткнулся на это, и думал, что добавлю свои мысли. Как предлагали другие, я бы рекомендовал вручную добавлять идентификаторы, но если вы действительно хотите что-то близкое к тому, что вы описали, вы можете использовать это:

var objectId = (function () {
    var allObjects = [];

    var f = function(obj) {
        if (allObjects.indexOf(obj) === -1) {
            allObjects.push(obj);
        }
        return allObjects.indexOf(obj);
    }
    f.clear = function() {
      allObjects = [];
    };
    return f;
})();

вы можете получить идентификатор любого объекта, позвонив objectId(obj). Затем, если вы хотите, чтобы идентификатор был свойством объекта, вы можете либо расширить прототип:

Object.prototype.id = function () {
    return objectId(this);
}

или вы можете вручную добавить идентификатор к каждому объекту, добавив аналогичную функцию в качестве метод.

главное предостережение заключается в том, что это предотвратит сборщик мусора от уничтожения объектов, когда они выпадают из области видимости... они никогда не выпадут из сферы allObjects массив, так что вы можете найти утечки памяти являются проблемой. Если ваш набор на использование этого метода, вы должны сделать это только для целей отладки. При необходимости, вы можете сделать objectId.clear() очистить allObjects и пусть GC делает свою работу (но с этого момента идентификаторы объектов будут сброшены).