"Array.prototype.slice: 'this' is not a JavaScript object" in IE8

As far as I understand, IE8 has access to the Array.prototype.slice method. But when I try to call it to turn a NodeList into an array, it gives me the error Array.prototype.slice: 'this' is not a JavaScript object . You can check here or see my code here:

HTML

 <div id="test">Test</div> 

Javascript

 var divs = document.getElementsByTagName('div'); divs = Array.prototype.slice.call(divs); console.log(divs); 

What's going on here?

+8
javascript dom arrays prototype nodelist
source share
4 answers

Update: NodeList can be thought of as an array in some way - you really don't need to do anything with this before you can iterate over it, for example:

 var aDivs = []; for (var = i = 0; i < divs.length; i++) { aDivs.push(divs[i]); } 

This will create an array with all nodes that match when running document.getElementsByTagName()

See this question for a full explanation of why slice works with NodeList in some browsers but not others, but it negates this suggestion from the spec:

Whether the slice function can be successfully applied to a host object is implementation dependent.

+8
source share

The error message is accurate: your nodelist is not a JavaScript object, it is a "Host object" that you cannot like regular JavaScript objects. Run this code in the IE8 JavaScript console:

 document.querySelectorAll("div") instanceof Object 

It returns false .

+2
source share

I assume that you want to keep the same content, even if the NodeList set has changed.

If this is the case, the bad news is: IE8 is broken. And it cannot handle the use of a slice in a NodeList.

Thus, you will need to use the backup and do a β€œslice” yourself if the fragment fails (using try / catch).

Please note: if you do not expect the DOM to change, and if the array-like object is sufficient, you can simply use the NodeList like any other array (except that it is not, and perhaps it will change if the DOM changes).

[edit] This is actually not a broken design, it is allowed by the standard (as indicated by the link in the comment by Kelvin Mackay)

0
source share

Using Array.prototype.slice to convert a NodeList array to an array will not work due to these two reasons:

  • slice method returns an existing array element.

  • Array.prototype not an instance of an Array object. It is simply a container of property objects that will be inherited by all instances of the Array object. Thus, it does not have the actual value of the array.

Converting a NodeList or HTMLCollection to an array is usually done using a for... loop. But this can also be done using a dynamically created disposable array:

 var divs = ([]).concat(document.getElementsByTagName('div')); 

This can also be done using the associated method call from Array.prototype , although this is unusual and not recommended. The below example is basically the same as above.

 var divs = Array.prototype.concat.apply([], document.getElementsByTagName('div')); 
0
source share

All Articles