Skip to content

Prototypal inheritance #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

1. `true`, taken from `rabbit`.
2. `null`, taken from `animal`.
3. `undefined`, there's no such property any more.
1. `true`, tiré de `rabbit`.
2. `null`, tiré de `animal`.
3. `undefined`, il n'y a plus une telle propriété.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Working with prototype
# Travailler avec prototype

Here's the code that creates a pair of objects, then modifies them.
Voici le code qui crée une paire d'objets, puis les modifie.

Which values are shown in the process?
Quelles sont les valeurs affichées dans le processus?

```js
let animal = {
Expand All @@ -28,4 +28,4 @@ delete animal.jumps;
alert( rabbit.jumps ); // ? (3)
```

There should be 3 answers.
Il devrait y avoir 3 réponses.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

1. Let's add `__proto__`:
1. Ajoutons `__proto__`:

```js run
let head = {
Expand Down Expand Up @@ -27,6 +27,6 @@
alert( table.money ); // undefined
```

2. In modern engines, performance-wise, there's no difference whether we take a property from an object or its prototype. They remember where the property was found and reuse it in the next request.
2. Dans les moteurs modernes, en termes de performances, il n’ya pas de différence selon que l’on prend une propriété d’un objet ou de son prototype. Ils se souviennent du lieu où la propriété a été trouvée et le réutilisent à la demande suivante.

For instance, for `pockets.glasses` they remember where they found `glasses` (in `head`), and next time will search right there. They are also smart enough to update internal caches if something changes, so that optimization is safe.
Par exemple, pour `pockets.glasses` ils se souviennent où ils ont trouvé `glasses` (dans `head`), et la prochaine fois rechercheront là. Ils sont également assez intelligents pour mettre à jour les caches internes en cas de changement, de sorte que l'optimisation est sécurisée.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Searching algorithm
# Algorithme de recherche

The task has two parts.
La tâche comporte deux parties.

We have objects:
Nous avons des objets:

```js
let head = {
Expand All @@ -27,5 +27,5 @@ let pockets = {
};
```

1. Use `__proto__` to assign prototypes in a way that any property lookup will follow the path: `pockets` -> `bed` -> `table` -> `head`. For instance, `pockets.pen` should be `3` (found in `table`), and `bed.glasses` should be `1` (found in `head`).
2. Answer the question: is it faster to get `glasses` as `pockets.glasses` or `head.glasses`? Benchmark if needed.
1. Utilisez `__proto__` pour attribuer des prototypes de manière à ce que toute recherche de propriété suive le chemin:`pockets` -> `bed` -> `table` -> `head`. Par exemple, `pocket.pen` devrait être `3` (trouvé dans `table`), et `bed.glasses` devrait être `1` (trouvé dans `head`).
2. Répondez à la question: est-il plus rapide d’obtenir `glasses` en tant que `pockets.glasses` ou `head.glasses`? Analyse si nécessaire.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
**The answer: `rabbit`.**
**La réponse: `rabbit`.**

That's because `this` is an object before the dot, so `rabbit.eat()` modifies `rabbit`.
C'est parce que `this` est un objet avant le point, donc `rabbit.eat()` modifie `rabbit`.

Property lookup and execution are two different things.
La recherche et l'exécution de propriétés sont deux choses différentes.

The method `rabbit.eat` is first found in the prototype, then executed with `this=rabbit`.
La méthode `rabbit.eat` est d'abord trouvée dans le prototype, puis exécutée avec `this=rabbit`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Where it writes?
# Où est-ce écrit?

We have `rabbit` inheriting from `animal`.
Nous avons `rabbit` héritant de `animal`.

If we call `rabbit.eat()`, which object receives the `full` property: `animal` or `rabbit`?
Si nous appelons `rabbit.eat()`, quel objet reçoit la propriété `full`: `animal` ou `rabbit`?

```js
let animal = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
Let's look carefully at what's going on in the call `speedy.eat("apple")`.
Examinons attentivement ce qui se passe dans l'appel `speedy.eat("apple")`.

1. The method `speedy.eat` is found in the prototype (`=hamster`), then executed with `this=speedy` (the object before the dot).
1. La méthode `speedy.eat` se trouve dans le prototype (`=hamster`), puis exécutée avec `this=speedy` (l'objet avant le point).

2. Then `this.stomach.push()` needs to find `stomach` property and call `push` on it. It looks for `stomach` in `this` (`=speedy`), but nothing found.
2. Ensuite, `this.stomach.push()` doit trouver la propriété `stomach` et appeler `push` dessus. Il cherche `stomach` dans `this` (`=speedy`), mais rien n'est trouvé.

3. Then it follows the prototype chain and finds `stomach` in `hamster`.
3. Ensuite, il suit la chaîne de prototypes et trouve `stomach` dans `hamster`.

4. Then it calls `push` on it, adding the food into *the stomach of the prototype*.
4. Ensuite, il appelle `push` dessus, en ajoutant la nourriture dans *stomach du prototype*.

So all hamsters share a single stomach!
Tous les hamsters partagent donc un seul estomac!

Both for `lazy.stomach.push(...)` and `speedy.stomach.push()`, the property `stomach` is found in the prototype (as it's not in the object itself), then the new data is pushed into it.
Tant pour `lazy.stomach.push(...)` et `speedy.stomach.push()`, la propriété `stomach` se trouve dans le prototype (comme il est pas dans l'objet lui-même), alors les nouvelles données sont poussé dedans.

Please note that such thing doesn't happen in case of a simple assignment `this.stomach=`:
Veuillez noter qu'une telle chose ne se produit pas dans le cas d'une simple affectation `this.stomach=`:

```js run
let hamster = {
stomach: [],

eat(food) {
*!*
// assign to this.stomach instead of this.stomach.push
// assigner à this.stomach au lieu de this.stomach.push
this.stomach = [food];
*/!*
}
Expand All @@ -34,17 +34,17 @@ let lazy = {
__proto__: hamster
};

// Speedy one found the food
// Speedy a trouvé la nourriture
speedy.eat("apple");
alert( speedy.stomach ); // apple

// Lazy one's stomach is empty
alert( lazy.stomach ); // <nothing>
// L'estomac de Lazy est vide
alert( lazy.stomach ); // <rien>
```

Now all works fine, because `this.stomach=` does not perform a lookup of `stomach`. The value is written directly into `this` object.
Maintenant, tout fonctionne bien, car `this.stomach=` n'effectue pas de recherche de `stomach`. La valeur est écrite directement dans l'objet `this`.

Also we can totally evade the problem by making sure that each hamster has their own stomach:
Nous pouvons également éviter le problème en nous assurant que chaque hamster a son propre `stomach`:

```js run
let hamster = {
Expand All @@ -69,12 +69,12 @@ let lazy = {
*/!*
};

// Speedy one found the food
// Speedy a trouvé la nourriture
speedy.eat("apple");
alert( speedy.stomach ); // apple

// Lazy one's stomach is empty
alert( lazy.stomach ); // <nothing>
// L'estomac de Lazy est vide
alert( lazy.stomach ); // <rien>
```

As a common solution, all properties that describe the state of a particular object, like `stomach` above, should be written into that object. That prevents such problems.
En tant que solution commune, toutes les propriétés qui décrivent l'état d'un objet particulier, comme `stomach` ci-dessus, devraient être écrits dans cet objet. Cela empêche de tels problèmes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Why two hamsters are full?
# Pourquoi deux hamsters sont pleins?

We have two hamsters: `speedy` and `lazy` inheriting from the general `hamster` object.
Nous avons deux hamsters: `speedy` et `lazy` héritant de l'objet général `hamster`.

When we feed one of them, the other one is also full. Why? How to fix it?
Lorsque nous nourrissons l'un d'eux, l'autre est également plein. Pourquoi? Comment y remédier?

```js run
let hamster = {
Expand All @@ -25,11 +25,11 @@ let lazy = {
__proto__: hamster
};

// This one found the food
// Celui-ci a trouvé la nourriture
speedy.eat("apple");
alert( speedy.stomach ); // apple

// This one also has it, why? fix please.
// Celui-ci l'a aussi, pourquoi? réparer s'il vous plaît.
alert( lazy.stomach ); // apple
```

Loading