代码之家  ›  专栏  ›  技术社区  ›  SimplGy ethanmad

javascript中按对象引用哈希

  •  2
  • SimplGy ethanmad  · 技术社区  · 10 年前

    任何人都需要通过javascript中的对象引用来散列吗?

    也许你想把 ul 通过其DOM节点的哈希,或通过构造对象的实例的属性,或许多其他东西。

    我读过 this 在稳定之前不要使用Weakmap。

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

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

    1 回复  |  直到 7 年前
        1
  •  2
  •   Jeremy J Starcher    10 年前

    你基本上已经找到了正确的方法,尽管我会在一个接口后面很好地完成它,并用我自己的接口完成 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];
    }