angular ie8 "Object doesn't support property or method 'hasOwnProperty'" workaround

stevethecollier picture stevethecollier · Dec 10, 2013 · Viewed 7.6k times · Source

I'm using angular-1.2.1.js on ie8 and getting the error:

Object doesn't support property or method 'hasOwnProperty' (inside the angular ForEach method)

function forEach(obj, iterator, context) {
  var key;
  if (obj) {
    if (isFunction(obj)){
      for (key in obj) {
        if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
          iterator.call(context, obj[key], key);
        }
      }
    } else if ...

According to this stackoverflow post, hasOwnProperty does not work in ie8 (at least not on the window object)

I'm not sure if things are acting weird because I'm using ie8 mode on windows 8 ie, but hasOwnProperty works when I use

var a = {b:'c'}
a.hasOwnProperty('b')  //true

why is ie8 throwing an error and how can I fix? thanks

Answer

Paul Sweatte picture Paul Sweatte · Nov 11, 2014

Use a map to convert the guarded statement:

 /* Check for existence */
 if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) 
    {
    iterator.call(context, obj[key], key);
    }

to a dispatch table:

 /* Map browser alias to stringified logic */
 var conditional = {"ie8": 
                    "key != 'prototype' && key != 'length' && key != 'name' && Object.prototype.hasOwnProperty.call(key, {})",

                    "w3c":
                    "key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)"
                   };

And a feature check to choose:

/* Ternary mapping of browser to logic */
var browser =  ("onpropertychange" in document) === true && (!!window.XDomainRequest) === true && (!!window.innerWidth) === false ? "ie8" : "w3c";

/* Evaluate valid result and pass to specified function */
if (eval(conditional[browser]) )
  {
  iterator.call(context, obj[key], key);
  }

References