Skip to content

Commit

Permalink
chore: translate prototype inheritance article
Browse files Browse the repository at this point in the history
Prototypal inheritance
  • Loading branch information
nazarepiedady authored Nov 2, 2024
2 parents da79189 + 19f7f94 commit 218098a
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 144 deletions.
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`, obtido de `rabbit`.
2. `null`, obtido de `animal`.
3. `undefined`, essa propriedade não existe mais.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Working with prototype
# Trabalhando com protótipos

Here's the code that creates a pair of objects, then modifies them.
Aqui está o código que cria um par de objetos, e depois os modifica.

Which values are shown in the process?
Que valores são mostrados no processo?

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

There should be 3 answers.
Deve haver 3 respostas.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

1. Let's add `__proto__`:
1. Vamos adicionar `__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. Em interpretadores de JavaScript modernos, em termos de performance (*performance-wise*), não há diferença entre obtermos uma propriedade de um objeto ou do seu protótipo. Eles se lembram onde a propriedade foi encontrada e reutilizam isso na próxima requisição.

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.
Por exemplo, para `pockets.glasses` eles se lembram onde encontraram `glasses` (em `head`), e na próxima vez vão procurar lá. Eles também são inteligentes o suficiente para atualizar caches internos se algo mudar, então essa otimização é segura.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Searching algorithm
# Algoritmo de busca

The task has two parts.
A tarefa tem duas partes.

Given the following objects:
Dados os objetos a seguir:

```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. Use `__proto__` para atribuir propriedades de forma que qualquer busca de propriedades siga o caminho: `pockets` -> `bed` -> `table` -> `head`. Por exemplo, `pockets.pen` deve ter o valor `3` (encontrado em `table`), e `bed.glasses` deve ter o valor `1` (encontrado em `head`).
2. Responda à seguinte questão: é mais rápido obter `glasses` como `pockets.glasses` ou como `head.glasses`? Compare (*benchmark*), se necessário.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
**The answer: `rabbit`.**
**A resposta: `rabbit`.**

That's because `this` is an object before the dot, so `rabbit.eat()` modifies `rabbit`.
Isso porque `this` é o objeto antes do ponto, então `rabbit.eat()` modifica `rabbit`.

Property lookup and execution are two different things.
Procurar e executar propriedades são duas coisas diferentes.

The method `rabbit.eat` is first found in the prototype, then executed with `this=rabbit`.
O método `rabbit.eat` primeiro é encontrado no protótipo, depois é exectado com `this=rabbit`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Where does it write?
# Onde vai escrever?

We have `rabbit` inheriting from `animal`.
Nós temos `rabbit` herdando de `animal`.

If we call `rabbit.eat()`, which object receives the `full` property: `animal` or `rabbit`?
Se nós chamarmos `rabbit.eat()`, que objeto recebe a propriedade `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")`.
Vamos ver cuidadosamente o que está acontecendo na chamada `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. O método `speedy.eat` é encontrado no protótipo (`=hamster`), e executado usando `this=speedy` (o objeto antes do ponto).

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. Então o método `this.stomach.push()` precisa de encontrar uma propriedade `stomach` e chamar o `push` nela. Ele procura por um `stomach` no `this` (`=speedy`), mas não encontra.

3. Then it follows the prototype chain and finds `stomach` in `hamster`.
3. Aí ele segue a cadeia de protótipos e encontra `stomach` no `hamster`.

4. Then it calls `push` on it, adding the food into *the stomach of the prototype*.
4. Por fim, ele chama o `push`, adicionando a comida (*food*) dentro do *`stomach` do protótipo*.

So all hamsters share a single stomach!
Então, todos os hamsters compartilham o mesmo estômago!

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.
Para ambos `lazy.stomach.push(...)` e `speedy.stomach.push()`, a propriedade `stomach` é encontrada no protótipo (porque não está no próprio objeto), e assim os novos dados são colocados nela.

Please note that such thing doesn't happen in case of a simple assignment `this.stomach=`:
Note que isso não acontece no caso de uma simples atribuição `this.stomach=`:

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

eat(food) {
*!*
// assign to this.stomach instead of this.stomach.push
// atribui o valor para this.stomach ao invés de usar this.stomach.push
this.stomach = [food];
*/!*
}
Expand All @@ -34,17 +34,17 @@ let lazy = {
__proto__: hamster
};

// Speedy one found the food
speedy.eat("apple");
alert( speedy.stomach ); // apple
// O Speedy acha a comida
speedy.eat("maçã");
alert( speedy.stomach ); // maçã

// Lazy one's stomach is empty
alert( lazy.stomach ); // <nothing>
// O estômago do Lazy continua vazio
alert( lazy.stomach ); // <vazio>
```

Now all works fine, because `this.stomach=` does not perform a lookup of `stomach`. The value is written directly into `this` object.
Agora tudo funciona bem, porque `this.stomach=` não procura por um `stomach`. O valor é escrito diretamente no `this` do objeto.

Also we can totally avoid the problem by making sure that each hamster has their own stomach:
Além disso, nós podemos evitar completamente o problema fazendo com que cada hamster tenha seu próprio estômago:

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

// Speedy one found the food
speedy.eat("apple");
alert( speedy.stomach ); // apple
// O Speedy acha a comida
speedy.eat("maçã");
alert( speedy.stomach ); // maçã

// Lazy one's stomach is empty
alert( lazy.stomach ); // <nothing>
// O estômago do Lazy continua vazio
alert( lazy.stomach ); // <vazio>
```

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.
É uma solução comum, fazer com que todas as propriedades que descrevem um estado particular do objeto, como o `stomach` acima, sejam escritas dentro do próprio objeto. Isso previne esses problemas.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Why are both hamsters full?
# Por que os dois hamsters estão cheios?

We have two hamsters: `speedy` and `lazy` inheriting from the general `hamster` object.
Nós temos dois hamsters: `speedy` e `lazy`, que herdam do objeto genérico `hamster`.

When we feed one of them, the other one is also full. Why? How can we fix it?
Quando nós alimentamos um deles, o outro também fica cheio. Por quê? Como podemos corrigir isso?

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

// This one found the food
speedy.eat("apple");
alert( speedy.stomach ); // apple
// Este aqui encontrou a comida
speedy.eat("maçã");
alert( speedy.stomach ); // maçã

// This one also has it, why? fix please.
alert( lazy.stomach ); // apple
// Esse aqui também comeu, por quê? Corrija, por favor.
alert( lazy.stomach ); // maçã
```

Loading

0 comments on commit 218098a

Please sign in to comment.