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

7.7k Views Asked by At

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

2

There are 2 best solutions below

0
On

I also encountered this error & found this edit on angular.js Github Source to resolve this issue:

if (obj) {
     if (isFunction(obj)){
       for (key in obj) {
//-        if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
//+        // This uglyness around hasOwnProperty is for IE8 to work properly (hasOwnProperty doesn't exist)
/*+*/        if (key != 'prototype' && key != 'length' && key != 'name' && (obj.hasOwnProperty && obj.hasOwnProperty(key) || Object.prototype.hasOwnProperty.call(obj, key))) {
           iterator.call(context, obj[key], key);
         }
       }

enter image description here

There is one more edit to make console.log work on IE8 https://github.com/pjparra/angular.js/commit/bcbf9409f10f5988f6946a7b0381eee5e6518989

Source:https://github.com/pjparra/angular.js/commit/8c2ed24412620d68a760cfab70e4dc27a49b9e91

0
On

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