Skip to content

Commit 23ed1bf

Browse files
committed
docs: translate one more piece of call-apply-decorators article
1 parent 8fc6d38 commit 23ed1bf

File tree

1 file changed

+37
-34
lines changed
  • 1-js/06-advanced-functions/09-call-apply-decorators

1 file changed

+37
-34
lines changed

1-js/06-advanced-functions/09-call-apply-decorators/article.md

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,28 @@ Para resumir, existem vários benefícios em utilizar um `cachingDecorator` sepa
6161
- A lógica de memorização é separada, não aumentou a complexidade da `slow` em si (se é que existia alguma).
6262
- Podemos combinar vários decoradores, se necessário (outros decoradores seguir-se-ão).
6363

64-
## Using "func.call" for the context
64+
## Usando `func.call` para o contexto
6565

66-
The caching decorator mentioned above is not suited to work with object methods.
66+
O decorador de memorização mencionado acima não é adequado para trabalhar com o métodos de objeto.
6767

68-
For instance, in the code below `worker.slow()` stops working after the decoration:
68+
Por exemplo, no código abaixo `worker.slow()` para de funcionar após a decoração:
6969

7070
```js run
71-
// we'll make worker.slow caching
71+
// faremos a memorização do `worker.slow`
7272
let worker = {
7373
someMethod() {
7474
return 1;
7575
},
7676

7777
slow(x) {
78-
// scary CPU-heavy task here
78+
// tarefa de processamento
79+
// assustadoramente pesado.
7980
alert("Called with " + x);
8081
return x * this.someMethod(); // (*)
8182
}
8283
};
8384

84-
// same code as before
85+
// o mesmo código que o anterior
8586
function cachingDecorator(func) {
8687
let cache = new Map();
8788
return function(x) {
@@ -96,49 +97,50 @@ function cachingDecorator(func) {
9697
};
9798
}
9899

99-
alert( worker.slow(1) ); // the original method works
100+
alert( worker.slow(1) ); // o método original funciona
100101

101-
worker.slow = cachingDecorator(worker.slow); // now make it caching
102+
worker.slow = cachingDecorator(worker.slow); // agora, memorize-o
102103

103104
*!*
104-
alert( worker.slow(2) ); // Whoops! Error: Cannot read property 'someMethod' of undefined
105+
alert( worker.slow(2) ); // Ups! Erro: Não é possível ler a 'someMethod' de indefinido
105106
*/!*
106107
```
107108

108-
The error occurs in the line `(*)` that tries to access `this.someMethod` and fails. Can you see why?
109+
O erro ocorre na linha `(*)` que tenta acessar a `this.someMethod` e falha. Podemos ver por quê?
109110

110-
The reason is that the wrapper calls the original function as `func(x)` in the line `(**)`. And, when called like that, the function gets `this = undefined`.
111+
A razão é que o embrulhador chama a função original como `func(x)` na linha `(**)`. E, quando chamada desta maneira, a função recebe `this = undefined`.
111112

112-
We would observe a similar symptom if we tried to run:
113+
Observaríamos um sintoma semelhante se tentássemos executar:
113114

114115
```js
115116
let func = worker.slow;
116117
func(2);
117118
```
118119

119-
So, the wrapper passes the call to the original method, but without the context `this`. Hence the error.
120+
Assim, o embrulhador passa a chamada para o método original, mas sem o contexto `this`. Daí o erro.
120121

121-
Let's fix it.
122+
Vamos corrigi-lo.
122123

123-
There's a special built-in function method [func.call(context, ...args)](mdn:js/Function/call) that allows to call a function explicitly setting `this`.
124+
Existe uma método especial de função embutido [`func.call(context, ...args)`](mdn:js/Function/call) que permite chamar uma função definindo explicitamente `this`.
124125

125-
The syntax is:
126+
A sintaxe é:
126127

127128
```js
128129
func.call(context, arg1, arg2, ...)
129130
```
130131

131-
It runs `func` providing the first argument as `this`, and the next as the arguments.
132+
Ele executa `func` fornecendo o primeiro argumento como `this`, e o próximo como os argumentos.
133+
134+
Para simplificar, estas duas chamadas fazem quase o mesmo:
132135

133-
To put it simply, these two calls do almost the same:
134136
```js
135137
func(1, 2, 3);
136138
func.call(obj, 1, 2, 3)
137139
```
138140

139-
They both call `func` with arguments `1`, `2` and `3`. The only difference is that `func.call` also sets `this` to `obj`.
141+
Ambas chamam `func` com os argumentos `1`, `2`, e `3`. A única diferença é que `func.call` também define `this` como `obj`.
140142

141-
As an example, in the code below we call `sayHi` in the context of different objects: `sayHi.call(user)` runs `sayHi` providing `this=user`, and the next line sets `this=admin`:
143+
Como exemplo, no código abaixo chamamos `sayHi` no contexto de diferentes objetos: `sayHi.call(user)` executa `sayHi` fornecendo `this=user`, e a próxima linha define `this=admin`:
142144

143145
```js run
144146
function sayHi() {
@@ -148,13 +150,13 @@ function sayHi() {
148150
let user = { name: "John" };
149151
let admin = { name: "Admin" };
150152

151-
// use call to pass different objects as "this"
153+
// usar `call` para passar
154+
// diferentes objetos como "this"
152155
sayHi.call( user ); // John
153156
sayHi.call( admin ); // Admin
154157
```
155158

156-
And here we use `call` to call `say` with the given context and phrase:
157-
159+
E aqui usamos `call` para chamar `say` com o dado contexto e frase:
158160

159161
```js run
160162
function say(phrase) {
@@ -163,11 +165,12 @@ function say(phrase) {
163165

164166
let user = { name: "John" };
165167

166-
// user becomes this, and "Hello" becomes the first argument
168+
// `user` torna-se `this`, e "Hello"
169+
// torna-se o primeiro argumento
167170
say.call( user, "Hello" ); // John: Hello
168171
```
169172

170-
In our case, we can use `call` in the wrapper to pass the context to the original function:
173+
No nosso caso, podemos usar `call` no embrulhador para passar o contexto para a função original:
171174

172175
```js run
173176
let worker = {
@@ -188,26 +191,26 @@ function cachingDecorator(func) {
188191
return cache.get(x);
189192
}
190193
*!*
191-
let result = func.call(this, x); // "this" is passed correctly now
194+
let result = func.call(this, x); // "this" é agora passado corretamente
192195
*/!*
193196
cache.set(x, result);
194197
return result;
195198
};
196199
}
197200

198-
worker.slow = cachingDecorator(worker.slow); // now make it caching
201+
worker.slow = cachingDecorator(worker.slow); // agora, memoriza-o
199202

200-
alert( worker.slow(2) ); // works
201-
alert( worker.slow(2) ); // works, doesn't call the original (cached)
203+
alert( worker.slow(2) ); // funciona
204+
alert( worker.slow(2) ); // funciona, não chama o original (memorizado)
202205
```
203206

204-
Now everything is fine.
207+
Agora está tudo bem.
205208

206-
To make it all clear, let's see more deeply how `this` is passed along:
209+
Para tornar tudo mais claro, veremos mais profundamente como `this` é passado adiante:
207210

208-
1. After the decoration `worker.slow` is now the wrapper `function (x) { ... }`.
209-
2. So when `worker.slow(2)` is executed, the wrapper gets `2` as an argument and `this=worker` (it's the object before dot).
210-
3. Inside the wrapper, assuming the result is not yet cached, `func.call(this, x)` passes the current `this` (`=worker`) and the current argument (`=2`) to the original method.
211+
1. Após a decoração, `worker.slow` agora é o embrulhador `function (x) { ... }`.
212+
2. Então quando `worker.slow(2)` é executado, o embrulhador recebe `2` como argumento e `this=worker` (é o objeto antes do ponto).
213+
3. Dentro do embrulhador, assumindo que o resultado ainda não está memorizado, `func.call(this, x)` passa o `this` atual (`=worker`) e o argumento atual (`=2`) para o método original.
211214

212215
## Going multi-argument
213216

0 commit comments

Comments
 (0)