Created
August 28, 2013 15:43
-
-
Save brettz9/6367532 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on work by John-David Dalton, Juriy Zaytsev, and Asen Bozhilov. | |
Object.forEach = (function () { | |
// Convenience aliases. | |
var toString = {}.toString, hasOwnProperty = {}.hasOwnProperty || | |
// Simulate `Object#hasOwnProperty` in Safari 2. | |
function (property) { | |
// Save the original prototype chain. | |
var original = this.__proto__, result; | |
// Break the prototype chain. | |
this.__proto__ = null; | |
result = property in this; | |
// Restore the prototype chain. | |
this.__proto__ = original; | |
return result; | |
}, forEach; | |
// The `Properties` constructor tests for bugs in the `for...in` algorithm. | |
function Properties() { | |
this.toString = 1; | |
} | |
Properties.prototype.toString = 1; | |
// Create and iterate over a new instance of the `Properties` constructor. | |
var properties = new Properties, property, length = 0; | |
for (property in properties) { | |
if (hasOwnProperty.call(properties, property)) { | |
length++; | |
} | |
} | |
if (!length) { | |
// JScript ignores shadowed non-enumerable properties. | |
properties = ['constructor', 'toString', 'valueOf', 'isPrototypeOf', | |
'hasOwnProperty', 'propertyIsEnumerable', 'toLocaleString']; | |
forEach = function forEach(object, iterator, context) { | |
var index = 0, property; | |
for (property in object) { | |
if (hasOwnProperty.call(object, property) && iterator.call(context, | |
object[property], property, object) === false) { | |
break; | |
} | |
} | |
// Provide a workaround for the JScript bug. | |
while ((property = properties[index++])) { | |
if (hasOwnProperty.call(object, property) && iterator.call(context, | |
object[property], property, object) === false) { | |
break; | |
} | |
} | |
}; | |
} else if (length == 2) { | |
// Safari 2 enumerates all shadowed and inherited properties. | |
forEach = function forEach(object, iterator, context) { | |
// The `prototype` property is handled inconsistently across browsers. | |
var isFunction = toString.call(object) == '[object Function]', | |
// Create a cache of iterated properties. | |
properties = {}, property; | |
for (property in object) { | |
// Skip the `prototype` property of functions. | |
if (!(isFunction && property == 'prototype') && !hasOwnProperty.call( | |
// Cache each property to prevent enumeration of inherited and shadowed | |
// properties. | |
properties, property) && (properties[property] = 1) && | |
hasOwnProperty.call(object, property) && iterator.call(context, | |
object[property], property, object) === false) { | |
break; | |
} | |
} | |
}; | |
} else { | |
forEach = function forEach(object, iterator, context) { | |
var isFunction = toString.call(object) == '[object Function]', property; | |
for (property in object) { | |
if (!(isFunction && property == 'prototype') && hasOwnProperty.call( | |
object, property) && iterator.call(context, object[property], property, | |
object) === false) { | |
break; | |
} | |
} | |
}; | |
} | |
return forEach; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment