“Array.prototype.slice: 'this' is not a JavaScript object” error in IE8

故事扮演 提交于 2019-12-19 05:56:16

问题


It is my understanding that IE8 has access to the Array.prototype.slice method. Yet 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 it out here, or look at 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?


回答1:


Update: A NodeList can be treated as an array in some ways - you don't actually have to do anything special with it before you can loop 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 of the nodes that matched when you ran document.getElementsByTagName()

See this question for a full explanation of why slice works with a NodeList in some browsers but not others, but it boils down this this sentence from the specification:

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




回答2:


The error message is accurate - your nodelist is not a JavaScript object, it is a "Host Object", which you can't necessarily pass around like regular JavaScript objects. Run this code in IE8's JavaScript console:

document.querySelectorAll("div") instanceof Object

It returns false.




回答3:


I assume that you want to keep the same content even if the NodeList set changes.

If it's that case, bad news : IE8 is broken. And it can't handle using slice on NodeList.

So you will need to use a fallback and make the "slice" yourself when slice fails (by using a try/catch).

Note that If you don't expect the DOM to change, and if an array-like object is enough, then you can just use the NodeList like any other array (except that it is not, and that perhaps it will be modified if the DOM changes).

[edit] Actually it's not a broken design, it's allowed by the standard (as stated by the link in Kelvin Mackay's comment)




回答4:


Using Array.prototype.slice to convert a NodeList to array won't work because of these two reasons:

  • slice method returns the existing array element(s).

  • Array.prototype is not an instance of Array object. It's merely an object container of properties that will be inherited by all Array object instances. So it doesn't have the actual array value.

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

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

It can also be done using bound call to a method from Array.prototype, although this is uncommon and isn't a recommended way. Below example is basically same as above.

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


来源:https://stackoverflow.com/questions/13317752/array-prototype-slice-this-is-not-a-javascript-object-error-in-ie8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!