JavaScript 中的唯一对象标识符

2022-08-30 02:36:20

我需要做一些实验,我需要知道javascript中对象的某种唯一标识符,这样我就可以看看它们是否相同。我不想使用相等运算符,我需要类似python中的id()函数的东西。

这样的事情存在吗?


答案 1

更新我下面的原始答案是6年前以适合时代和我的理解的风格写的。为了回应评论中的一些对话,更现代的方法如下:

    (function() {
        if ( typeof Object.id == "undefined" ) {
            var id = 0;

            Object.id = function(o) {
                if ( typeof o.__uniqueid == "undefined" ) {
                    Object.defineProperty(o, "__uniqueid", {
                        value: ++id,
                        enumerable: false,
                        // This could go either way, depending on your 
                        // interpretation of what an "id" is
                        writable: false
                    });
                }

                return o.__uniqueid;
            };
        }
    })();
    
    var obj = { a: 1, b: 1 };
    
    console.log(Object.id(obj));
    console.log(Object.id([]));
    console.log(Object.id({}));
    console.log(Object.id(/./));
    console.log(Object.id(function() {}));

    for (var k in obj) {
        if (obj.hasOwnProperty(k)) {
            console.log(k);
        }
    }
    // Logged keys are `a` and `b`

如果您有过时的浏览器要求,请在此处查看 浏览器兼容性。Object.defineProperty

原始答案保留在下面(而不仅仅是在更改历史记录中),因为我认为比较是有价值的。


您可以给以下几个旋转。这还为您提供了在其构造函数或其他位置显式设置对象 ID 的选项。

    (function() {
        if ( typeof Object.prototype.uniqueId == "undefined" ) {
            var id = 0;
            Object.prototype.uniqueId = function() {
                if ( typeof this.__uniqueid == "undefined" ) {
                    this.__uniqueid = ++id;
                }
                return this.__uniqueid;
            };
        }
    })();
    
    var obj1 = {};
    var obj2 = new Object();
    
    console.log(obj1.uniqueId());
    console.log(obj2.uniqueId());
    console.log([].uniqueId());
    console.log({}.uniqueId());
    console.log(/./.uniqueId());
    console.log((function() {}).uniqueId());

请注意确保用于内部存储唯一 ID 的任何成员都不会与其他自动创建的成员名称发生冲突。


答案 2

就我的观察而言,这里发布的任何答案都可能产生意想不到的副作用。

在ES2015兼容的环境中,您可以使用WeakMap来避免任何副作用。

const id = (() => {
    let currentId = 0;
    const map = new WeakMap();

    return (object) => {
        if (!map.has(object)) {
            map.set(object, ++currentId);
        }

        return map.get(object);
    };
})();

id({}); //=> 1