JavaScript vs jQuery 元素集合

译自JavaScript vs jQuery HTML Collections

HTML集合(HTMLCollection)对象是 document.getElementsByTagNamedocument.getElementsByName 以及 document.getElementsByClassName(并非所有浏览器都支持)这些方法的返回值。表面上看,它们与数组相似,因为它们有length属性,并且元素可以通过索引[index]被访问。然而,它们并不是数组。诸如 push()slice()sort() 也都不支持。

考虑下面的HTML片段:

<body>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
    <p>Paragraph 3</p>
</body>

让我们用 getElementsByTagName 和 jQuery选择器 选取所有的段落节点:

var pCollection = document.getElementsByTagName("p");
var pQuery = $("p");
console.log("pCollection.length: ", pCollection.length);
console.log("pQuery.length: ", pQuery.length);

两种方式都返回相同的节点所以集合的长度都是3:

pCollection.length: 3  
pQuery.length: 3

我们现在增加一个新段落元素到文档片段里然后再回过头来看集合:

// add new paragraph  
var newp = document.createElement("p");  
newp.appendChild(document.createTextNode("Paragraph 4"));  
document.body.appendChild(newp);  
//  
// display length  
console.log("pCollection.length: ", pCollection.length);  
console.log("pQuery.length: ", pQuery.length);

结果是:

pCollection.length: 4  
pQuery.length: 3

HTML集合对象是“活”的。无论底层文档如何变化,它们都自动更新。jQuery以及大多数其他JS库虽然同样适用诸如 document.getElementsByTagName() 的方法但却将结果拷贝到真正的数组里。所以,那只是那时查询文档时状态:它从来不被更新。

两种方法各有优缺点,比如,下面的代码导致一个无限循环,因为HTML集合的长度始终跟着

元素的增加而增加:

var pCollection = document.getElementsByTagName("p");  
for (var i = 0; i < pCollection.length; i++) {  
    document.body.appendChild(pCollection[i].cloneNode(true));  
}

这就是说,在重复相同选择的情况下,原生更快的实时的HTML集合比静态的jQuery节点集合更有用。幸运的是,当我们需要操作元素的时候,我们可以传递任何的集合给jQuery

var pCollection = document.getElementsByTagName("p");  
// ... add nodes, do work, etc ...  
$(pCollection).addClass("myclass");

jQuery以及其他库可以节约开发成本,但我们总是该检查是否有可能在不增加额外文件情况以及处理开销的情况下,用原生JS编写更有效率的代码。

译后语

因为很短,看完后就直接译了…