任何人都需要在javascript中通过对象引用进行哈希?
也许您希望通过其DOM节点的哈希对ul
s的子项进行分组,或者通过构造对象的实例或许多其他事物对属性进行分组。
我已阅读this并且在稳定之前不想使用Weakmaps。
我能想到的唯一方法是将父项存储在数组中并在那里强制执行引用唯一性,然后通过数组中引用的索引进行散列。 (例如找到LI的所有常见UL父母):
var lis = document.getElementsByTagName('li'); // Get all objects
var parent, key, li;
for (var i=0; i<lis.length; i++ ) { // For every LI
storeItemByParent(lis[i], lis[i].parentNode);
}
var parents = [];
var itemsByParent = {};
function storeItemByParent (item, parent){
var key;
// Does this parent already exist? if so, use that index as the hash key
for (var j=0; j<parents.length; j++) {
if(parents[j] === parent) {
key = j;
break;
}
}
// This is a new parent? If so, track it and use that index as the hash key
if (key == undefined) {
parents.push(parent);
key = parents.length;
}
// Finally! The lis in a hash by parent "id".
itemsByParent[key] = itemsByParent[key] || [];
itemsByParent[key].push(item);
}
是否有更好的方法来存储属性或子项或附加到对象实例的其他内容而不将它们添加为对象本身的属性?
答案 0 :(得分:2)
你已经在那里找到了正确的方法,不过我已经很好地将它包装在一个界面后面,完成了我自己的add
和find
方法。
您可以使用<array>.indexOf
进行编码,在所有现代浏览器中都支持,并在需要时轻松填充。
然而,你的方法有一个缺点:
如果从DOM中删除了一个元素,那么该元素将不会被垃圾收集,因为你的数组仍然保留了对它的引用。
虽然这不是一个表演限制因素,但当然值得记住。
然而,您可以采取完全不同的方法。可能不会更好 - 但不同。
请原谅代码中的任何小错误,我正在写这个徒手:
function elementDataHash = {};
function setElementData(el, data) {
var hash = el.getAttribute("data-element-hash");
if !(hash) {
// http://stackoverflow.com/questions/6860853/generate-random-string-for-div-id
hash = generateRandomString();
el.setAttribute("data-element-hash", hash);
}
elementDataHash[hash] = data;
}
function getElementData(el) {
var hash = el.getAttribute("data-element-hash");
return elementDataHash[hash];
}