【问题标题】:Hash by object reference in javascript在javascript中按对象引用散列
【发布时间】:2014-10-12 01:30:23
【问题描述】:

有人需要在 javascript 中通过对象引用来散列吗?

也许您想通过 uls 的 DOM 节点的哈希值或构造对象实例的属性或许多其他东西对子级进行分组。

我已阅读 this 并且不想使用 Wea​​kmap,直到它们稳定为止。

我能想到的唯一方法是将父母存储在一个数组中并在那里强制引用唯一性,然后通过数组中引用的索引进行散列。 (示例是查找 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);
}

有没有更好的方法来存储附加到对象实例的属性或子对象或其他东西,而不将它们添加为对象本身的属性?

【问题讨论】:

  • 你能给出所有元素的ID吗?然后你可以使用 ID 作为哈希键。
  • 如果你愿意使用 jQuery,它的.data() 方法几乎可以实现你想要的。
  • 是的——实现我自己的.data() 版本几乎是这个想法:)
  • 你可能想看看jQuery是如何实现它的。

标签: javascript hash map


【解决方案1】:

你已经找到了正确的方法,尽管我会用我自己的 addfind 方法将它很好地包装在一个界面后面。

您可以使用&lt;array&gt;.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];
}

【讨论】:

  • 关于indexOf 和垃圾收集的好消息。是的,完全应该包含在一个界面中,正如this answer 所示。 “字典”是正确的 CS 术语吗?我也喜欢另一种方法:元素上的属性存储随机散列,散列用于获取数据。类似的 GC 问题,对吧?每当删除一个 el 时,都必须从哈希表中删除该条目。
  • @SimpleAsCouldBe 取决于存储数据的大小。使用第二种方法,可以遍历 elementDataHash 并查看这些元素中是否有任何元素在 DOM 中存在,如果没有,则清理该条目。至于 Dictionary 这个词——我不使用这个词来表示常规的 JavaScript 对象,因为它会暗示来自其他背景的人的不真实的东西。 (例如,在 C# 中,字典可以有任何类型的键,它不必是 string。)
  • @SimpleAsCouldBe Head's up -- 我修复了el.setAttribute("data-element-hash", hash);
猜你喜欢
  • 2018-12-31
  • 2014-02-16
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 2016-09-08
相关资源
最近更新 更多