Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm getting this error message only in IE8, and I don't know how to convert the existing function for IE8 compatibility.

_initEvents : function() {
     var self = this;

     Array.prototype.slice.call(this.menuItems).forEach(function(el, i) {
         var trigger = el.querySelector('a');

         if (self.touch) {
             trigger.addEventListener('touchstart', function(ev) {
                   self._openMenu(this, ev); 
               });
         }
         else {
             trigger.addEventListener('click', function(ev) {
                   self._openMenu(this, ev);
               });  
        }
     });
   window.addEventListener('resize', function(ev) {
         self._resizeHandler();
     });

},

the above is just a part of it, I dont think the rest is needed. The error happens here:

 Array.prototype.slice.call( this.menuItems )
like image 242
Mike Avatar asked Jul 01 '13 01:07

Mike


People also ask

How do you slice an array of objects in JavaScript?

JavaScript Array slice() The slice() method returns selected elements in an array, as a new array. The slice() method selects from a given start, up to a (not inclusive) given end. The slice() method does not change the original array.

What does array slice do in JavaScript?

The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end ( end not included) where start and end represent the index of items in that array.


1 Answers

When you call:

this.menuItems = this.el.querySelectorAll( '.cbp-hsmenu > li' );

the object assigned to menuItems is a static NodeList, which is a host object. Then when you do:

Array.prototype.slice.call( this.menuItems )

you are calling a built–in method with a host object as this. In IE 8 and lower (and probably lots of other older browsers), you can't do that (there is no specification that says you should, though modern browsers let you).

The simple solution is to convert menuItems to an array using some other method than call, or to add a shim for Array.prototype.forEach and use CrazyTrain's suggestion:

Array.prototype.forEach.call(this.menuItems, func...)

because in browsers without a built–in forEach, it will be a native method and work just fine. But for robust code, replace all that with a simple for loop.

like image 55
RobG Avatar answered Nov 12 '22 17:11

RobG