This commit is contained in:
Ilya Kantor 2019-08-03 00:35:50 +03:00
parent 0757d51080
commit a894b9e278

View file

@ -101,7 +101,6 @@ The method is automatically taken from the prototype, like this:
The prototype chain can be longer: The prototype chain can be longer:
```js run ```js run
let animal = { let animal = {
eats: true, eats: true,
@ -131,10 +130,10 @@ alert(longEar.jumps); // true (from rabbit)
![](proto-animal-rabbit-chain.svg) ![](proto-animal-rabbit-chain.svg)
There are actually only two limitations: There are only two limitations:
1. The references can't go in circles. JavaScript will throw an error if we try to assign `__proto__` in a circle. 1. The references can't go in circles. JavaScript will throw an error if we try to assign `__proto__` in a circle.
2. The value of `__proto__` can be either an object or `null`, other types (like primitives) are ignored. 2. The value of `__proto__` can be either an object or `null`. Other types are ignored.
Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others. Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others.
@ -171,7 +170,7 @@ From now on, `rabbit.walk()` call finds the method immediately in the object and
![](proto-animal-rabbit-walk-2.svg) ![](proto-animal-rabbit-walk-2.svg)
That's for data properties only, not for accessors. If a property is a getter/setter, then it behaves like a function: getters/setters are looked up in the prototype. Accessor properties are an exception, as assignment is handled by a setter function. So writing to such a property is actually the same as calling a function.
For that reason `admin.fullName` works correctly in the code below: For that reason `admin.fullName` works correctly in the code below:
@ -247,7 +246,7 @@ The resulting picture:
![](proto-animal-rabbit-walk-3.svg) ![](proto-animal-rabbit-walk-3.svg)
If we had other objects like `bird`, `snake` etc inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects. If we had other objects like `bird`, `snake` etc inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method call would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects.
As a result, methods are shared, but the object state is not. As a result, methods are shared, but the object state is not.
@ -313,8 +312,8 @@ Note, there's one funny thing. Where is the method `rabbit.hasOwnProperty` comin
The answer is simple: it's not enumerable. Just like all other properties of `Object.prototype`, it has `enumerable:false` flag. That's why they are not listed. The answer is simple: it's not enumerable. Just like all other properties of `Object.prototype`, it has `enumerable:false` flag. That's why they are not listed.
```smart header="All other iteration methods ignore inherited properties" ```smart header="Almost all other key/value-getting methods ignore inherited properties"
All other key/value-getting methods, such as `Object.keys`, `Object.values` and so on ignore inherited properties. Almost all other key/value-getting methods, such as `Object.keys`, `Object.values` and so on ignore inherited properties.
They only operate on the object itself. Properties from the prototype are taken into account. They only operate on the object itself. Properties from the prototype are taken into account.
``` ```