Skip to content

Commit 06f9927

Browse files
committed
remove extra article
1 parent 8e251ab commit 06f9927

File tree

4 files changed

+63
-83
lines changed

4 files changed

+63
-83
lines changed

1-js/08-prototypes/01-prototype-inheritance/article.md

+63
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,73 @@ If we had other objects like `bird`, `snake` etc inheriting from `animal`, they
251251

252252
As a result, methods are shared, but the object state is not.
253253

254+
## for..in loop
255+
256+
The `for..in` loops over inherited properties too.
257+
258+
For instance:
259+
260+
```js run
261+
let animal = {
262+
eats: true
263+
};
264+
265+
let rabbit = {
266+
jumps: true,
267+
__proto__: animal
268+
};
269+
270+
*!*
271+
// only own keys
272+
alert(Object.keys(rabbit)); // jumps
273+
*/!*
274+
275+
*!*
276+
// inherited keys too
277+
for(let prop in rabbit) alert(prop); // jumps, then eats
278+
*/!*
279+
```
280+
281+
If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) property named `key`.
282+
283+
So we can filter out inherited properties (or do something else with them):
284+
285+
```js run
286+
let animal = {
287+
eats: true
288+
};
289+
290+
let rabbit = {
291+
jumps: true,
292+
__proto__: animal
293+
};
294+
295+
for(let prop in rabbit) {
296+
let isOwn = rabbit.hasOwnProperty(prop);
297+
alert(`${prop}: ${isOwn}`); // jumps: true, then eats: false
298+
}
299+
```
300+
301+
Here we have the following inheritance chain: `rabbit`, then `animal`, then `Object.prototype` (because `animal` is a literal object `{...}`, so it's by default), and then `null` above it:
302+
303+
![](rabbit-animal-object.png)
304+
305+
Note, there's one funny thing. Where is the method `rabbit.hasOwnProperty` coming from? Looking at the chain we can see that the method is provided by `Object.prototype.hasOwnProperty`. In other words, it's inherited.
306+
307+
...But why `hasOwnProperty` does not appear in `for..in` loop, if it lists all inherited properties? The answer is simple: it's not enumerable. Just like all other properties of `Object.prototype`. That's why they are not listed.
308+
309+
```smart header="All other iteration methods ignore inherited properties"
310+
All other key/value-getting methods, such as `Object.keys`, `Object.values` and so on ignore inherited properties.
311+
312+
They only operate on the object itself. Properties from the prototype are taken into account.
313+
```
314+
315+
254316
## Summary
255317

256318
- In JavaScript, all objects have a hidden `[[Prototype]]` property that's either another object or `null`.
257319
- We can use `obj.__proto__` to access it (a historical getter/setter, there are other ways, to be covered soon).
258320
- The object referenced by `[[Prototype]]` is called a "prototype".
259321
- If we want to read a property of `obj` or call a method, and it doesn't exist, then JavaScript tries to find it in the prototype. Write/delete operations work directly on the object, they don't use the prototype (unless the property is actually a setter).
260322
- If we call `obj.method()`, and the `method` is taken from the prototype, `this` still references `obj`. So methods always work with the current object even if they are inherited.
323+
- The `for..in` loop iterates over both own and inherited properties. All other key/value-getting methods only operate on the object itself.

1-js/08-prototypes/05-getting-all-properties/article.md

-83
This file was deleted.

0 commit comments

Comments
 (0)