JavaScript 对象 ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2020670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript Object Id
提问by treznik
Do JavaScript objects/variables have some sort of unique identifier? Like Ruby has object_id. I don't mean the DOM id attribute, but rather some sort of memory address of some kind.
JavaScript 对象/变量是否具有某种唯一标识符?就像 Ruby 有object_id. 我不是指 DOM id 属性,而是指某种内存地址。
采纳答案by Xavi
No, objects don't have a built in identifier, though you can add one by modifying the object prototype. Here's an example of how you might do that:
不,对象没有内置标识符,但您可以通过修改对象原型来添加标识符。以下是您可能如何执行此操作的示例:
(function() {
var id = 0;
function generateId() { return id++; };
Object.prototype.id = function() {
var newId = generateId();
this.id = function() { return newId; };
return newId;
};
})();
That said, in general modifying the object prototype is considered very bad practice. I would instead recommend that you manually assign an id to objects as needed or use a touchfunction as others have suggested.
也就是说,通常修改对象原型被认为是非常糟糕的做法。相反,我建议您根据需要手动为对象分配一个 id 或使用touch其他人建议的函数。
回答by Phrogz
If you want to lookup/associate an object with a unique identifier without modifying the underlying object, you can use a WeakMap:
如果要在不修改底层对象的情况下查找/关联具有唯一标识符的对象,可以使用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
Using a WeakMapensures that the objects can still be garbage-collected.
使用 aWeakMap确保对象仍然可以被垃圾收集。
回答by KalEl
Actually, you don't need to modify the objectprototype. The following should work to 'obtain' unique ids for any object, efficiently enough.
实际上,您不需要修改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;
}
回答by Nathan MacInnes
I've just come across this, and thought I'd add my thoughts. As others have suggested, I'd recommend manually adding IDs, but if you really want something close to what you've described, you could use this:
我刚刚遇到这个,并想我会添加我的想法。正如其他人所建议的那样,我建议手动添加 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;
})();
You can get any object's ID by calling objectId(obj). Then if you want the id to be a property of the object, you can either extend the prototype:
您可以通过调用获取任何对象的 ID objectId(obj)。然后,如果您希望 id 成为对象的属性,则可以扩展原型:
Object.prototype.id = function () {
return objectId(this);
}
or you can manually add an ID to each object by adding a similar function as a method.
或者您可以通过添加与方法类似的功能来手动为每个对象添加 ID。
The major caveat is that this will prevent the garbage collector from destroying objects when they drop out of scope... they will never drop out of the scope of the allObjectsarray, so you might find memory leaks are an issue. If your set on using this method, you should do so for debugging purpose only. When needed, you can do objectId.clear()to clear the allObjectsand let the GC do its job (but from that point the object ids will all be reset).
主要的警告是,这将防止垃圾收集器在对象超出范围时销毁对象……它们永远不会超出allObjects数组的范围,因此您可能会发现内存泄漏是一个问题。如果您设置使用此方法,则应仅出于调试目的而这样做。需要时,您可以objectId.clear()清除allObjectsGC 并让 GC 完成其工作(但从那时起,对象 ID 将全部重置)。

