Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript对象Id_Javascript_Unique Id - Fatal编程技术网

JavaScript对象Id

JavaScript对象Id,javascript,unique-id,Javascript,Unique Id,JavaScript对象/变量是否具有某种唯一标识符?就像Ruby有对象id。我指的不是DOM id属性,而是某种内存地址。不,对象没有内置标识符,不过可以通过修改对象原型添加一个标识符。下面是一个示例,说明了如何做到这一点: (function() { var id = 0; function generateId() { return id++; }; Object.prototype.id = function() { var newId = g

JavaScript对象/变量是否具有某种唯一标识符?就像Ruby有
对象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;
    };
})();

也就是说,一般来说,修改对象原型被认为是非常糟糕的做法。相反,我建议您根据需要手动为对象分配id,或者像其他人建议的那样使用
touch
功能。

实际上,您不需要修改
对象
原型。以下内容可以有效地“获取”任何对象的唯一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;
}

我刚刚遇到这个问题,我想补充一下我的想法。正如其他人所建议的,我建议手动添加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
数组的范围,所以您可能会发现内存泄漏是一个问题。如果设置为使用此方法,则只应出于调试目的而这样做。需要时,您可以执行
objectId.clear()
以清除
allObjects
,并让GC执行其工作(但从那时起,对象ID将全部重置)。

如果您希望在不修改基础对象的情况下查找/关联具有唯一标识符的对象,可以使用:

//注意对象必须是对象或数组,
//不是字符串、数字等基本值。
var objIdMap=new WeakMap,objectCount=0;
函数objectId(object){
如果(!objIdMap.has(object))objIdMap.set(object,++objectCount);
返回objIdMap.get(object);
}
VarO1={},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
而不是
Map
可以确保对象仍然可以被垃圾收集。

您是否希望使用对象id来比较对象?请看,这肯定不是真的,因为问题在别处得到了回答。甚至都不接近。@ErikAronesty我同意。在链接线程中,没有任何地方可以回答对象是否具有内置id的问题。请注意,如果您希望对象之后具有不同的id,那么这将无法很好地处理大多数复制对象的方法。事实上,您需要一个特殊的“copyObject”函数来专门考虑这个id。您还必须确保与在其他库中使用“\uuuuobj\uid”没有冲突。这在ActionScript中要容易得多,它的Dictionary对象对键(包括用作键的对象)使用严格的相等比较。事实上,您可能可以在JS中编写一个字典类,以这种方式自动将ID附加到作为键添加到其中的对象。这就像量子力学;在你尝试用这个函数观察它们之前,它们是不存在的。haha.ActionScript 3有一个字典对象,它使用严格的相等性进行键比较,因此可以使用对象作为键。JavaScript中是否有等价物,或者您是否必须为每个对象手动构造唯一的id(通过object.prototype或手动添加id来选择对象)?不幸的是,JavaScript没有类似的功能。听起来您必须给对象id,然后按照您的建议将这些id用作对象中的键。也就是说,如果你真的想变得聪明,你可以通过重写
toString
方法实现“id对象”,并像这样使用它们
id=newid();cache[id]=obj
。这有点疯狂,但很有趣。下面是我写的一篇文章,更详细地解释了这种技术:好吧,我刚刚找到了原因。jQuery还覆盖了ID,当我覆盖它时,不知何故我的页面断了。哈。可以所以我只想避免命名问题,祈祷好运。这个例子可以作为闭包和原型继承的一个很好的使用例子。我认为这是一个缓慢但健壮的解决方案,可以稍加改进:``var objectId=(function(){var mem=[];var f=function(obj){var r=mem.indexOf(obj);if(r===-1){r=mem.length;mem.push(obj);}return r;};f.reset=function(){return mem=[];};return f;}();“``@loochen1990,我想你会对它的速度感到惊讶。(但是你是对的,最好是把index()放进去)结果是一个变量,尽管我会从枯燥的角度而不是从优化的角度来论证。)只要GC问题能够得到有效管理,我认为您必须拥有大量的对象才能注意到任何显著的性能影响。最佳答案!使用内存O(n),其中n是您关心的ID的对象数(而不是n=所有对象)并且不影响垃圾收集。好极了!甚至可以在IE11中工作(在Win10上测试)