Skip to content

Commit a9deb11

Browse files
committed
Merge pull request BonsaiDen#243 from matthewgertner/master
Added details about using hasOwnProperty in ES5
2 parents 2d910a1 + 4e91eae commit a9deb11

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

doc/en/object/forinloop.md

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
Just like the `in` operator, the `for in` loop traverses the prototype
44
chain 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

1818
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.
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` -
3848
have 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.
4154
When 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

doc/en/object/hasownproperty.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ does **not** traverse the prototype chain.
2121
foo.hasOwnProperty('bar'); // false
2222
foo.hasOwnProperty('goo'); // true
2323

24-
Only `hasOwnProperty` will give the correct and expected result; this is
25-
essential when iterating over the properties of any object. There is **no** other
26-
way to exclude properties that are not defined on the object itself, but
27-
somewhere on its prototype chain.
24+
Only `hasOwnProperty` will give the correct and expected result. See the section
25+
on [`for in` loops](#object.forinloop) for more details on when to use
26+
`hasOwnProperty` when iterating over object
27+
properties.
2828

2929
### `hasOwnProperty` as a Property
3030

@@ -53,6 +53,6 @@ necessary to use an *external* `hasOwnProperty` to get correct results.
5353

5454
Using `hasOwnProperty` is the **only** reliable method to check for the
5555
existence of a property on an object. It is recommended that `hasOwnProperty`
56-
is used in **every** [`for in` loop](#object.forinloop) to avoid errors from
57-
extended native [prototypes](#object.prototype).
56+
be used in many cases when iterating over object properties as described
57+
in the section on [`for in` loops](#object.forinloop).
5858

0 commit comments

Comments
 (0)