3
3
Just like the ` in ` operator, the ` for in ` loop traverses the prototype
4
4
chain when iterating over the properties of an object.
5
5
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 `
8
8
> property of an array.
9
-
9
+
10
10
// Poisoning Object.prototype
11
11
Object.prototype.bar = 1;
12
12
@@ -16,9 +16,18 @@ chain when iterating over the properties of an object.
16
16
}
17
17
18
18
Since 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.
22
31
23
32
> ** Note:** Since ` for in ` always traverses the complete prototype chain, it
24
33
> 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
32
41
}
33
42
}
34
43
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 ` -
38
48
have been extended.
39
49
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.
41
54
When this framework is included, ` for in ` loops that do not use
42
55
` hasOwnProperty ` are guaranteed to break.
43
56
44
57
### In Conclusion
45
58
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.
49
64
50
65
[ 1 ] : http://www.prototypejs.org/
51
66
0 commit comments