Большинство списков узлов в DOM (например, вернулся из getElementsBy*
, querySelectorAll
и Node.childNodes
) не являются простыми Массивы, а скорее NodeList
объекты. NodeList
объекты обычно «живые», при этом изменения в документе автоматически распространяются на объект Nodelist
. (Исключением является результатом querySelectorAll
, который не жить!)
Так как вы можете видеть в вашем примере, если вы извлечь NodeList всех a
элементов, а затем добавить еще один a
элемент в документе, который a
появится в вашем объекте NodeList.
Вот почему небезопасно выполнять итерацию через NodeList при одновременном внесении изменений в документ. Например, этот код будет вести себя удивительными способами:
var NodeListA = document.getElementsByTagName('a');
for (var i=0; i<NodeListA.length; ++i) {
// UNSAFE: don't do this!
NodeListA[i].parentNode.removeChild(NodeListA[i]);
}
Что произойдет, вы закончите пропуски элементов! Или итерацию назад с конца NodeList, либо скопируйте NodeList в простой массив (который не будет обновляться), а затем сработает с этим.
Подробнее о NodeLists на странице Mozilla MDC site.