33Just like the ` in ` operator, the ` for in ` loop traverses the prototype
44chain when iterating over the properties of an object.
55
6- > ** Note:** The ` for in ` loop will ** not** iterate over any properties that
7- > have their ` enumerable ` attribute set to ` false ` ; for example, the ` length `
6+ > ** Note:** The ` for in ` loop will ** not** iterate over any properties that
7+ > have their ` enumerable ` attribute set to ` false ` ; for example, the ` length `
88> property of an array.
9-
9+
1010 // Poisoning Object.prototype
1111 Object.prototype.bar = 1;
1212
@@ -16,9 +16,18 @@ chain when iterating over the properties of an object.
1616 }
1717
1818Since it is not possible to change the behavior of the ` for in ` loop itself, it
19- is necessary to filter out the unwanted properties inside the loop body;
20- this is done using the [ ` hasOwnProperty ` ] ( #object.hasownproperty ) method of
21- ` Object.prototype ` .
19+ is necessary to filter out the unwanted properties inside the loop body. In
20+ ECMAScript 3 and older, this is done using the [ ` hasOwnProperty ` ] ( #object.hasownproperty )
21+ method of ` Object.prototype ` .
22+ 23+ Since ECMAScript 5, ` Object.defineProperty ` can be used with
24+ ` enumerable ` set to ` false ` to add properties to objects (including ` Object ` )
25+ without these properties being enumerated. In this case it is reasonable
26+ to assume in application code that any enumerable properties have been added
27+ for a reason and to omit ` hasOwnProperty ` , since it makes code more verbose and less
28+ readable. In library code ` hasOwnProperty ` should still be used since
29+ assumptions cannot be made about which enumerable properties might reside
30+ on the prototype chain.
2231
2332> ** Note:** Since ` for in ` always traverses the complete prototype chain, it
2433> will get slower with each additional layer of inheritance added to an object.
@@ -32,20 +41,26 @@ this is done using the [`hasOwnProperty`](#object.hasownproperty) method of
3241 }
3342 }
3443
35- This version is the only correct one to use. Due to the use of ` hasOwnProperty ` , it
36- will ** only** print out ` moo ` . When ` hasOwnProperty ` is left out, the code is
37- prone to errors in cases where the native prototypes - e.g. ` Object.prototype ` -
44+ This version is the only correct one to use with older versions of ECMAScript.
45+ Due to the use of ` hasOwnProperty ` , it will ** only** print out ` moo ` .
46+ When ` hasOwnProperty ` is left out, the code is prone to errors in cases where
47+ the native prototypes - e.g. ` Object.prototype ` -
3848have been extended.
3949
40- One widely used framework that extends ` Object.prototype ` is [ Prototype] [ 1 ] .
50+ In newer versions of ECMAScript, non-enumerable properties can be defined with
51+ ` Object.defineProperty ` , reducing the risk of iterating over properties without
52+ using ` hasOwnProperty ` . Nonetheless, care must be taken when using older
53+ libraries like [ Prototype] [ 1 ] , which does not yet take advantage of new ECMAScript features.
4154When this framework is included, ` for in ` loops that do not use
4255` hasOwnProperty ` are guaranteed to break.
4356
4457### In Conclusion
4558
46- It is recommended to ** always** use ` hasOwnProperty ` . Assumptions should never
47- be made about the environment the code is running in, or whether the native
48- prototypes have been extended or not.
59+ It is recommended to ** always** use ` hasOwnProperty ` in ECMAScript 3 or lower, as well as
60+ in library code. Assumptions should never be made in these environments about whether
61+ the native prototypes have been extended or not. Since ECMAScript 5, ` Object.defineProperty `
62+ makes it possible to define non-enumerable properties and to omit ` hasOwnProperty ` in
63+ application code.
4964
5065[ 1 ] : http://www.prototypejs.org/
5166
0 commit comments