JavaScript对象ID
JavaScript对象/variables是否有某种唯一标识符? 像Ruby有object_id
。 我不是指DOM id属性,而是某种内存地址。
不,对象没有内置的标识符,但可以通过修改对象原型来添加标识符。 以下是您可能如何做的一个例子:
(function() { var id = 0; function generateId() { return id++; }; Object.prototype.id = function() { var newId = generateId(); this.id = function() { return newId; }; return newId; }; })();
这就是说,通常修改对象的原型被认为是非常糟糕的做法。 相反,我build议您根据需要手动将对象分配给对象,或使用其他人所build议的touch
function。
如果您想查找/关联具有唯一标识符的对象而不修改底层对象,则可以使用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
原型。 以下应该有效地“获得”任何对象的唯一ID。
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; }
我刚刚遇到了这个,并认为我会加上我的想法。 正如其他人所build议的,我build议手动添加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)
来获得任何对象的ID。 那么如果你想让id成为对象的属性,你可以扩展原型:
Object.prototype.id = function () { return objectId(this); }
或者您可以通过添加一个类似的函数作为方法手动添加一个ID到每个对象。
主要的注意事项是,这将防止垃圾收集器在超出范围时销毁对象…它们绝不会从allObjects
数组的范围中allObjects
,因此您可能会发现内存泄漏是一个问题。 如果你使用这个方法,你应该这样做只用于debugging目的。 当需要的时候,你可以做objectId.clear()
来清除allObjects
并让GC完成它的工作(但是从这一点开始对象ID将全部被重置)。