如何为javascript对象生成密钥

时间:2014-07-02 07:24:45

标签: javascript object map

我想实现一个ObjectSet类,它包含一组对象引用。在下面的实现1中,我使用Array来存储对象。在put / remove函数中,我迭代整个数组以查找传入的对象。设置的大小非常大,并且频繁调用函数。迭代的表现是一个问题。

在实现2中,我使用一个Object作为映射来存储对象引用。以这种方式,它不需要迭代put / remove函数中的所有对象。表现会更好。但Object属性必须是字符串。我无法使用该对象作为关键。问题是:是否有任何算法可以为对象生成唯一键?

实施1 - 在数组中存储对象引用

function ObjectSet() {
    this.store = []; // Array
}
ObjectSet.prototype = {
    put: function( obj) {
        var store = this.store;
        for (var i = 0; i < store.length; i++) {
            if (store[i] === obj) {
                return;
            }
        };
    },
    remove: function( obj ) {
        var store = this.store;
        for (var i = 0; i < store.length; i++) {
            if (store[i] === obj) {
                store.splice(i, 1);
            }
        };
    }
};

实施2 - 在对象中存储对象引用

function ObjectSet() {
    this.store = {}; // Object
}
ObjectSet.prototype = {
    put: function( obj) {
        var key = generateKeyFromObject(obj);
        if(!this.store[ key ]){
            this.store[ key ] = obj;
        }
    },
    remove: function( obj ) {
        var key = generateKeyFromObject(obj);
        if(this.store[ key ]){
            delete this.store[ key ];
        }
    }
};
function generateKeyFromObject(obj){
    // Question: How to generate a unique key for an object?
}

============更新2014年7月2日================

根据答案/评论粘贴我的实现。

// Use the global index to avoid the clash when the same object is added to different sets.
var index = 1, key='##key';
function generateKeyFromObject(obj){
    if(!obj[key]){
        var uniqueKey="##uniqueKey" + (index++).toString();
        Object.defineProperty(obj, key, {
            writable: false,
            enumerable: false,
            configurable: false,
            value: uniqueKey
        });
   }
    return obj[key];
}

1 个答案:

答案 0 :(得分:2)

如果向要插入的对象添加属性没有问题:

function ObjectSet() 
{
    var id = 0;

    this.nextId = function() { // id generator function
        return ++id;
    };

    this.store = {}; // Object
}

ObjectSet.prototype = {
    put: function(obj) {
        if (!obj.id) {
            obj.id = this.nextId();
            this.store[obj.id] = obj;
        }
    },
    remove: function(obj) {
        if (obj.id && this.store[obj.id]) {
            delete this.store[key];
        }
    }
};

正如评论中所指出的,如果可以在集合之间共享对象,这将成为一个问题;在这种情况下,需要将相同的id生成器用于所使用的所有对象。

var nextId = function() {
    var id = 0;

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