我想实现一个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];
}
答案 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;
};
}();