| 229 | // Internal: Normalizes the `for...in` iteration algorithm across |
| 230 | // environments. Each enumerated key is yielded to a `callback` function. |
| 231 | var forOwn = function (object, callback) { |
| 232 | var size = 0, Properties, members, property; |
| 233 | |
| 234 | // Tests for bugs in the current environment's `for...in` algorithm. The |
| 235 | // `valueOf` property inherits the non-enumerable flag from |
| 236 | // `Object.prototype` in older versions of IE, Netscape, and Mozilla. |
| 237 | (Properties = function () { |
| 238 | this.valueOf = 0; |
| 239 | }).prototype.valueOf = 0; |
| 240 | |
| 241 | // Iterate over a new instance of the `Properties` class. |
| 242 | members = new Properties(); |
| 243 | for (property in members) { |
| 244 | // Ignore all properties inherited from `Object.prototype`. |
| 245 | if (isProperty.call(members, property)) { |
| 246 | size++; |
| 247 | } |
| 248 | } |
| 249 | Properties = members = null; |
| 250 | |
| 251 | // Normalize the iteration algorithm. |
| 252 | if (!size) { |
| 253 | // A list of non-enumerable properties inherited from `Object.prototype`. |
| 254 | members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; |
| 255 | // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable |
| 256 | // properties. |
| 257 | forOwn = function (object, callback) { |
| 258 | var isFunction = getClass.call(object) == functionClass, property, length; |
| 259 | var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty; |
| 260 | for (property in object) { |
| 261 | // Gecko <= 1.0 enumerates the `prototype` property of functions under |
| 262 | // certain conditions; IE does not. |
| 263 | if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) { |
| 264 | callback(property); |
| 265 | } |
| 266 | } |
| 267 | // Manually invoke the callback for each non-enumerable property. |
| 268 | for (length = dontEnums.length; property = dontEnums[--length];) { |
| 269 | if (hasProperty.call(object, property)) { |
| 270 | callback(property); |
| 271 | } |
| 272 | } |
| 273 | }; |
| 274 | } else { |
| 275 | // No bugs detected; use the standard `for...in` algorithm. |
| 276 | forOwn = function (object, callback) { |
| 277 | var isFunction = getClass.call(object) == functionClass, property, isConstructor; |
| 278 | for (property in object) { |
| 279 | if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { |
| 280 | callback(property); |
| 281 | } |
| 282 | } |
| 283 | // Manually invoke the callback for the `constructor` property due to |
| 284 | // cross-environment inconsistencies. |
| 285 | if (isConstructor || isProperty.call(object, (property = "constructor"))) { |
| 286 | callback(property); |
| 287 | } |
| 288 | }; |