UNPKG

2.33 kBJavaScriptView Raw
1var hasOwn = require('./hasOwn');
2
3 var _hasDontEnumBug,
4 _dontEnums;
5
6 function checkDontEnum(){
7 _dontEnums = [
8 'toString',
9 'toLocaleString',
10 'valueOf',
11 'hasOwnProperty',
12 'isPrototypeOf',
13 'propertyIsEnumerable',
14 'constructor'
15 ];
16
17 _hasDontEnumBug = true;
18
19 for (var key in {'toString': null}) {
20 _hasDontEnumBug = false;
21 }
22 }
23
24 /**
25 * Similar to Array/forEach but works over object properties and fixes Don't
26 * Enum bug on IE.
27 * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
28 */
29 function forIn(obj, fn, thisObj){
30 var key, i = 0;
31 // no need to check if argument is a real object that way we can use
32 // it for arrays, functions, date, etc.
33
34 //post-pone check till needed
35 if (_hasDontEnumBug == null) checkDontEnum();
36
37 for (key in obj) {
38 if (exec(fn, obj, key, thisObj) === false) {
39 break;
40 }
41 }
42
43
44 if (_hasDontEnumBug) {
45 var ctor = obj.constructor,
46 isProto = !!ctor && obj === ctor.prototype;
47
48 while (key = _dontEnums[i++]) {
49 // For constructor, if it is a prototype object the constructor
50 // is always non-enumerable unless defined otherwise (and
51 // enumerated above). For non-prototype objects, it will have
52 // to be defined on this object, since it cannot be defined on
53 // any prototype objects.
54 //
55 // For other [[DontEnum]] properties, check if the value is
56 // different than Object prototype value.
57 if (
58 (key !== 'constructor' ||
59 (!isProto && hasOwn(obj, key))) &&
60 obj[key] !== Object.prototype[key]
61 ) {
62 if (exec(fn, obj, key, thisObj) === false) {
63 break;
64 }
65 }
66 }
67 }
68 }
69
70 function exec(fn, obj, key, thisObj){
71 return fn.call(thisObj, obj[key], key, obj);
72 }
73
74 module.exports = forIn;
75
76