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

2019-02-22 04:53发布

问题:

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 )

回答1:

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.