Недопустимо вызывать Array.prototype.slice
для объекта NodeList
, возвращаемого свойством childNodes
(или различными другими методами DOM).
Обычно было бы неправильно вызывать Thing.prototype.method
для чего-либо, кроме экземпляра Thing
, однако браузеры традиционно разрешали - а стандарт ECMAScript Third Edition требует - особый случай для многих Array.prototype
методов, чтобы они могут быть вызваны для любого объекта native-JavaScript, который достаточно похож на Array
. Это означает, в частности, что они могут использоваться на объекте arguments
, который выглядит как Array
, но на самом деле это не так.
Однако NodeList
и другие объекты коллекции в DOM не определены как собственные объекты JavaScript; им разрешено быть «объектами хоста», которые полностью реализуются браузером, а не языком. Все ставки на хост-объекты сняты ...
Возможность успешного применения функции слайса к хост-объекту зависит от реализации.
Так что Array.prototype.slice
может не работать для NodeList, а в IE до версии 8 действительно не будет.
Если вы хотите сделать копию NodeList в виде обычного массива, вам придется сделать это длинным, но безопасным способом:
Array.fromSequence= function(seq) {
var arr= new Array(seq.length);
for (var i= seq.length; i-->0;)
if (i in seq)
arr[i]= seq[i];
return arr;
};
var stack = [Array.fromSequence(document.body.childNodes)];
Кстати, вы можете сделать этот компоновщик немного проще, используя textnode.splitText
, и я бы очень настороженно отнесся к использованию глобальных свойств RegExp
, как если бы в одном из промежуточных вызовов они произвели неожиданную работу с регулярным выражением: потеряюсь Смотреть на предмет совпадения обычно лучше. См. этот вопрос , чтобы узнать о другой атаке, по сути, той же самой проблемы.