jQuery中 的 unique() 函数实现了对 DOM ELement按出现位置进行排序并去除重复元素的功能。使用方法如下:
<html>
<head></head><body οnlοad="test()"><div id="div_1"> <div id="div_2" /></div><div id="div_3" /><script type='text/javascript' src='jquery.js'></script><script type='text/javascript'>function test() { var divs = [ document.getElementById('div_3'), document.getElementById('div_1'), document.getElementById('div_2'), document.getElementById('div_2'), document.getElementById('div_1') ]; var html = show('before uinque', divs); $.unique(divs); html += show('after uinque', divs); document.write(html);}function show(name, divs) { var html = ''; for (var i = 0; i < divs.length; ++i) { html += divs[i].getAttribute('id') + '<br />'; } return name + ':<br />' + html + '<br />';}</script></body></html>从函数名来看,应该主要是用于去除重复元素的,为什么同时又先对 DOM Element 进行排序?为了解释这个问题,先让我们试一下不事先进行排序的情况下需要如何去除重复。
不排序的去除重复元素的实现
$ = function() { return { unique: function(elems) { for (var i = 0; i < elems.length; ++i) { for (var j = i + 1; j < elems.length; ++j) { if (elems[i] === elems[j]) { elems.splice(i--, 1); break; } } } return elems; }, unique2: function(elemsWithId) { var obj = {}; for (var i = 0; i < elemsWithId.length; ++i) { var elem = elemsWithId[i]; obj[elem.getAttribute('id')] = elem; } elemsWithId.length = 0; for (var id in obj) { elemsWithId.push(obj[id]) } return elemsWithId; } } }();
实现一使用了两重循环,算法复杂度为O(n^2);实现思路比较直观,即遍历数组,看每个元素是否与后面的元素重复,有重复则移除;但当DOM Element数量较多时性能较差,而jQuery中对大量元素进行去除重复的操作时很普遍的。 实现二将 Object 当做 HashMap/HashSet 来使用,算法复杂度为O(n);遗憾的是JavaScript中无法直接用 DOM ELement 作为 Object 的 key ,因此只能将 id 作为 key ,然而并非所有的 DOM Element 都是有 id 的,所以这种方法并不通用。而自己实现一个高性能的 HashSet(还需要自己动手计算 DOM Element 的 Hash Code ),工作量有比较大。