From 025fe80e3bff8ea3e4e638cbcea5fcf30e6449db Mon Sep 17 00:00:00 2001 From: odsantos Date: Thu, 7 Nov 2019 23:12:32 +0100 Subject: [PATCH 1/4] add translate to object-methods directory files --- .../2-check-syntax/solution.md | 26 +-- .../04-object-methods/2-check-syntax/task.md | 8 +- .../04-object-methods/3-why-this/solution.md | 21 +- .../04-object-methods/3-why-this/task.md | 9 +- .../4-object-property-this/solution.md | 19 +- .../4-object-property-this/task.md | 11 +- .../7-calculator/_js.view/test.js | 6 +- .../7-calculator/solution.md | 2 +- .../04-object-methods/7-calculator/task.md | 15 +- .../8-chain-calls/_js.view/test.js | 10 +- .../8-chain-calls/solution.md | 6 +- .../04-object-methods/8-chain-calls/task.md | 14 +- .../04-object-methods/article.md | 215 +++++++++--------- 13 files changed, 177 insertions(+), 185 deletions(-) diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md index e2e87de7c..3554a5be4 100644 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md +++ b/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md @@ -1,6 +1,6 @@ -**Error**! +**Erro**! -Try it: +Tente isto: ```js run let user = { @@ -8,22 +8,22 @@ let user = { go: function() { alert(this.name) } } -(user.go)() // error! +(user.go)() // erro! ``` -The error message in most browsers does not give understanding what went wrong. +A mensagem de erro, na maior parte dos navegadores (*browsers*), não nos dá uma compreensão do que ocorre de errado. -**The error appears because a semicolon is missing after `user = {...}`.** +**O erro aparece porque falta um ponto-e-vírgula depois de `user = {...}`.** -JavaScript does not assume a semicolon before a bracket `(user.go)()`, so it reads the code like: +JavaScript não assume um ponto-e-vírgula antes do parêntese de `(user.go)()`, por isso lê o código como: ```js no-beautify let user = { go:... }(user.go)() ``` -Then we can also see that such a joint expression is syntactically a call of the object `{ go: ... }` as a function with the argument `(user.go)`. And that also happens on the same line with `let user`, so the `user` object has not yet even been defined, hence the error. +Assim, podemos também observar que, tal expressão conjunta é sintáticamente uma chamada do objeto `{ go: ... }` como uma função, tomando `(user.go)` como argumento. E, isso também ocorre na mesma linha que `let user`, então o objeto `user` ainda não foi definido, e por isto o erro. -If we insert the semicolon, all is fine: +Se inserirmos o ponto-e-vírgula, tudo estará bem: ```js run let user = { @@ -31,13 +31,7 @@ let user = { go: function() { alert(this.name) } }*!*;*/!* -(user.go)() // John +(user.go)() // 'John' ``` -Please note that brackets around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters. - - - - - - +Por favor, note que os parênteses em `(user.go)` nada aqui fazem. Geralmente, eles estabelecem a ordem das operações, mas aqui o ponto `.` já funciona à partida, então não têm efeito algum. Apenas, aquele ponto-e-vírgula importa. diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md index f40d68735..ef43de48c 100644 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md +++ b/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md @@ -1,10 +1,10 @@ -importance: 2 +importância: 2 --- -# Syntax check +# Verificação sintática -What is the result of this code? +Qual o resultado deste código? ```js no-beautify @@ -16,4 +16,4 @@ let user = { (user.go)() ``` -P.S. There's a pitfall :) +P.S. Existe um falha :) diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md b/1-js/04-object-basics/04-object-methods/3-why-this/solution.md index 89bc0d722..c48fcdceb 100644 --- a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/3-why-this/solution.md @@ -1,22 +1,21 @@ -Here's the explanations. +Aqui estão as explicações. -1. That's a regular object method call. +1. É uma regular invocação do método do objeto. -2. The same, brackets do not change the order of operations here, the dot is first anyway. +2. O mesmo. Aqui, os parênteses não alteram a ordem das operações, o ponto já funciona à primeira. -3. Here we have a more complex call `(expression).method()`. The call works as if it were split into two lines: +3. Aqui, temos uma chamada `(expression).method()` mais complexa. A chamada funciona como se fosse particionada em duas linhas: ```js no-beautify - f = obj.go; // calculate the expression - f(); // call what we have + f = obj.go; // calcula a expressão + f(); // invoca o resultado ``` - Here `f()` is executed as a function, without `this`. + Aqui, `f()` é executada como uma função, sem `this`. -4. The similar thing as `(3)`, to the left of the dot `.` we have an expression. +4. Algo similar a `(3)`, à esquerda do ponto `.` temos uma expressão. -To explain the behavior of `(3)` and `(4)` we need to recall that property accessors (dot or square brackets) return a value of the Reference Type. - -Any operation on it except a method call (like assignment `=` or `||`) turns it into an ordinary value, which does not carry the information allowing to set `this`. +Para explicar o comportamento de `(3)` e `(4)`, recordemo-nos que propriedades acessoras (o ponto ou os parênteses retos) retornam um valor do Tipo *Reference*. +Qualquer operação com elas (como, atribuição `=` ou `||`), exceto a chamada a um método, o transforma num valor ordinário, o qual não transporta a informação necessária para configurar `this`. diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/task.md b/1-js/04-object-basics/04-object-methods/3-why-this/task.md index f22de29cc..919f17220 100644 --- a/1-js/04-object-basics/04-object-methods/3-why-this/task.md +++ b/1-js/04-object-basics/04-object-methods/3-why-this/task.md @@ -1,12 +1,12 @@ -importance: 3 +importância: 3 --- -# Explain the value of "this" +# Explique o valor de "this" -In the code below we intend to call `user.go()` method 4 times in a row. +No código abaixo, pretendemos invocar o método `user.go()` 4 vezes seguidas. -But calls `(1)` and `(2)` works differently from `(3)` and `(4)`. Why? +Mas, as chamadas `(1)` e `(2)` funcionam de forma diferente do que as `(3)` e `(4)`. Porquê? ```js run no-beautify let obj, method; @@ -23,4 +23,3 @@ obj.go(); // (1) [object Object] (obj.go || obj.stop)(); // (4) undefined ``` - diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md index f5773ec2c..14f42f296 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md @@ -1,6 +1,6 @@ -**Answer: an error.** +**Resposta: um erro.** -Try it: +Tente isto: ```js run function makeUser() { return { @@ -12,17 +12,18 @@ function makeUser() { let user = makeUser(); alert( user.ref.name ); // Error: Cannot read property 'name' of undefined + // (Erro: não é possível ler a propriedade 'name' de undefined) ``` -That's because rules that set `this` do not look at object literals. +Isto, porque regras que estabelecem `this` não têm em conta objetos literais. -Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method. +Aqui, o valor de `this` dentro de `makeUser()` está `undefined`, porque é invocado como uma função, não como um método. -And the object literal itself has no effect on `this`. The value of `this` is one for the whole function, code blocks and object literals do not affect it. +E um objeto literal não possui qualquer efeito sobre `this`. O valor de `this` é o mesmo para toda uma função, e tanto blocos de código como objetos literais não exercem qualquer influência sobre ele. -So `ref: this` actually takes current `this` of the function. +Assim, na realidade `ref: this` recebe o valor atual `this` da função. -Here's the opposite case: +Aqui, o caso oposto: ```js run function makeUser() { @@ -38,9 +39,9 @@ function makeUser() { let user = makeUser(); -alert( user.ref().name ); // John +alert( user.ref().name ); // 'John' ``` -Now it works, because `user.ref()` is a method. And the value of `this` is set to the object before dot `.`. +Agora funciona, porque `user.ref()` é um método. E, o valor de `this` já é uma referência ao objeto antes do ponto `.`. diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md index 4784b082c..200392df1 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md @@ -1,12 +1,12 @@ -importance: 5 +importância: 5 --- -# Using "this" in object literal +# Usando "this" num objeto literal -Here the function `makeUser` returns an object. +Aqui, a função `makeUser` retorna um objeto. -What is the result of accessing its `ref`? Why? +Qual o resultado de aceder à sua `ref`? Porquê? ```js function makeUser() { @@ -18,6 +18,5 @@ function makeUser() { let user = makeUser(); -alert( user.ref.name ); // What's the result? +alert( user.ref.name ); // Qual o resultado? ``` - diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js index 1f71eda4c..1c47c6a1e 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js @@ -2,7 +2,7 @@ describe("calculator", function() { - context("when 2 and 3 entered", function() { + context("quando são entrados 2 e 3", function() { beforeEach(function() { sinon.stub(window, "prompt"); @@ -16,11 +16,11 @@ describe("calculator", function() { prompt.restore(); }); - it("the sum is 5", function() { + it("a soma é 5", function() { assert.equal(calculator.sum(), 5); }); - it("the multiplication product is 6", function() { + it("o produto da multiplicação é 6", function() { assert.equal(calculator.mul(), 6); }); }); diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md index 459997624..b604c3c9c 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md @@ -1,5 +1,5 @@ -```js run demo solution +```js execute a solução demo let calculator = { sum() { return this.a + this.b; diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md index aa22608ec..acce94c85 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md @@ -1,18 +1,18 @@ -importance: 5 +importância: 5 --- -# Create a calculator +# Crie uma calculadora -Create an object `calculator` with three methods: +Crie um objeto `calculator` com três métodos: -- `read()` prompts for two values and saves them as object properties. -- `sum()` returns the sum of saved values. -- `mul()` multiplies saved values and returns the result. +- `read()` pergunta (*prompts*) por dois valores e os guarda (*saves*) como propriedades de um objeto. +- `sum()` retorna a soma dos valores guardados. +- `mul()` multiplica os valores guardados e retorna o resultado. ```js let calculator = { - // ... your code ... + // ... o seu código ... }; calculator.read(); @@ -21,4 +21,3 @@ alert( calculator.mul() ); ``` [demo] - diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js index a2b17fcc4..e9cb1f8de 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js @@ -8,24 +8,24 @@ describe('Ladder', function() { ladder.step = 0; }); - it('up() should return this', function() { + it('up() deveria retornar this', function() { assert.equal(ladder.up(), ladder); }); - it('down() should return this', function() { + it('down() deveria retornar this', function() { assert.equal(ladder.down(), ladder); }); - it('showStep() should call alert', function() { + it('showStep() deveria chamar alert', function() { ladder.showStep(); assert(alert.called); }); - it('up() should increase step', function() { + it('up() deveria incrementar step', function() { assert.equal(ladder.up().up().step, 2); }); - it('down() should decrease step', function() { + it('down() deveria decrementar step', function() { assert.equal(ladder.down().step, -1); }); diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index 2b47873fc..620384a37 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -1,6 +1,6 @@ -The solution is to return the object itself from every call. +A solução será retornar o próprio objeto em cada chamada. -```js run demo +```js execute demo let ladder = { step: 0, up() { @@ -26,7 +26,7 @@ let ladder = { ladder.up().up().down().up().down().showStep(); // 1 ``` -We also can write a single call per line. For long chains it's more readable: +Podemos também escrever uma única chamada por linha. Para longas cadeias é mais legível: ```js ladder diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md index eca9f4e92..8c38cbe9c 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md @@ -1,10 +1,10 @@ -importance: 2 +importância: 2 --- -# Chaining +# Encadeamento -There's a `ladder` object that allows to go up and down: +Existe um objeto `ladder` (escada) que permite subir e descer: ```js let ladder = { @@ -15,13 +15,13 @@ let ladder = { down() { this.step--; }, - showStep: function() { // shows the current step + showStep: function() { // mostra o atual degrau alert( this.step ); } }; ``` -Now, if we need to make several calls in sequence, can do it like this: +Agora, se precisarmos de fazer várias chamadas em sequência, podemos fazê-las desta forma: ```js ladder.up(); @@ -30,10 +30,10 @@ ladder.down(); ladder.showStep(); // 1 ``` -Modify the code of `up`, `down` and `showStep` to make the calls chainable, like this: +Modifique o código de `up`, `down` e `showStep` para tornar as chamadas encadeáveis, como: ```js ladder.up().up().down().showStep(); // 1 ``` -Such approach is widely used across JavaScript libraries. +Tal abordagem é amplamente utilizada em bibliotecas (*libraries*) de JavaScript. diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 0418adee0..3e6f5ef45 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -1,6 +1,6 @@ -# Object methods, "this" +# Métodos do objeto, "this" -Objects are usually created to represent entities of the real world, like users, orders and so on: +Objectos, geralmente são criados como representação de entidades no mundo real, como utilizadores, encomendas e assim por diante: ```js let user = { @@ -9,13 +9,13 @@ let user = { }; ``` -And, in the real world, a user can *act*: select something from the shopping cart, login, logout etc. +E, no mundo real, um utilizador pode *interagir*: selecionar algo de um carrinho de compras, *login*, *logout*, etc. -Actions are represented in JavaScript by functions in properties. +As interações, são representadas em JavaScript por funções em propriedades. -## Method examples +## Exemplos de métodos -For the start, let's teach the `user` to say hello: +Para começar, ensinemos ao `user` a dizer olá: ```js run let user = { @@ -25,22 +25,22 @@ let user = { *!* user.sayHi = function() { - alert("Hello!"); + alert("Olá!"); }; */!* -user.sayHi(); // Hello! +user.sayHi(); // Olá! ``` -Here we've just used a Function Expression to create the function and assign it to the property `user.sayHi` of the object. +Aqui, acabamos de empregar uma Expressão de Função (*Function Expression*) para criar uma função e a atribuir à propriedade do objeto `user.sayHi`. -Then we can call it. The user can now speak! +Depois, a podemos invocar. O utilizador pode agora falar! -A function that is the property of an object is called its *method*. +Uma função que seja uma propriedade de um objeto, é chamada de seu *método* (*method*). -So, here we've got a method `sayHi` of the object `user`. +Assim, temos o método `sayHi` do objeto `user`. -Of course, we could use a pre-declared function as a method, like this: +Evidentemente, poderiamos usar uma função pré-declarada como método. Desta forma: ```js run let user = { @@ -48,61 +48,61 @@ let user = { }; *!* -// first, declare +// primeiro, declare function sayHi() { alert("Hello!"); }; -// then add as a method +// Depois adicine como método user.sayHi = sayHi; */!* user.sayHi(); // Hello! ``` -```smart header="Object-oriented programming" -When we write our code using objects to represent entities, that's called an [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP". +```smart header="Programação orientada por objetos" +Quando escrevemos o nosso código empregando objetos para representar entidades, é chamada de [Programação orientada a objetos](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_objetos) (*object-oriented programming*), abreviadamente: "OOP". -OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides or "Object-Oriented Analysis and Design with Applications" by G.Booch, and more. +OOP (Programação orientada por objetos) é algo grande, uma ciência interessante por si mesma. Como escolher as entidades certas? Como organizar a interação enter elas? É arquitetura, e existem grandes livros neste tópico, como "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides ou "Object-Oriented Analysis and Design with Applications" by G.Booch, e mais. ``` -### Method shorthand +### Abreviação de método -There exists a shorter syntax for methods in an object literal: +Existe uma sintaxe mais curta para métodos num objeto literal: ```js -// these objects do the same +// estes objetos fazem o mesmo let user = { sayHi: function() { - alert("Hello"); + alert("Olá"); } }; -// method shorthand looks better, right? +// a abreviação de método tem melhor aspeto, não tem? let user = { *!* - sayHi() { // same as "sayHi: function()" + sayHi() { // o mesmo que "sayHi: function()" */!* - alert("Hello"); + alert("Olá"); } }; ``` -As demonstrated, we can omit `"function"` and just write `sayHi()`. +Como demonstrado, podemos omitir `"function"` e apenas escrever `sayHi()`. -To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases the shorter syntax is preferred. +Na verdade, as notações não são completamente idênticas. Existem diferenças subtis em relação à herança do objeto (a ser estudado mais adiante), mas por ora elas não interessam. Em quase todos os casos, a sintaxe mais curta é preferível. -## "this" in methods +## "*this*" em métodos -It's common that an object method needs to access the information stored in the object to do its job. +É comum que um método de um objeto precise de aceder à informação armazenada no objeto para executar a sua tarefa. -For instance, the code inside `user.sayHi()` may need the name of the `user`. +Por exemplo, o código dentro de `user.sayHi()` pode precisar do nome do `user`. -**To access the object, a method can use the `this` keyword.** +**Para aceder ao objeto, um método pode usar a palavra-chave `this`.** -The value of `this` is the object "before dot", the one used to call the method. +O valor de `this` é o objeto "antes do ponto", o utilizado para chamar o método. -For instance: +Por exemplo: ```js run let user = { @@ -120,9 +120,9 @@ let user = { user.sayHi(); // John ``` -Here during the execution of `user.sayHi()`, the value of `this` will be `user`. +Aqui, durante a execução de `user.sayHi()`, o valor de `this` será `user`. -Technically, it's also possible to access the object without `this`, by referencing it via the outer variable: +Tecnicamente, também é possível aceder ao objeto sem `this`, por meio de uma referência numa variável externa: ```js let user = { @@ -131,16 +131,16 @@ let user = { sayHi() { *!* - alert(user.name); // "user" instead of "this" + alert(user.name); // "user" em vez de "this" */!* } }; ``` -...But such code is unreliable. If we decide to copy `user` to another variable, e.g. `admin = user` and overwrite `user` with something else, then it will access the wrong object. +...Mas tal código não é fiável. Se decidirmos copiar `user` para outra variável, por exemplo `admin = user` e colocar outro valor em `user`, então a cópia irá aceder ao valor errado. -That's demonstrated below: +Isso, é demonstrado abaixo: ```js run let user = { @@ -149,7 +149,7 @@ let user = { sayHi() { *!* - alert( user.name ); // leads to an error + alert( user.name ); // leva a um erro */!* } @@ -157,18 +157,18 @@ let user = { let admin = user; -user = null; // overwrite to make things obvious +user = null; // atribui outro valor, para ser óbvio -admin.sayHi(); // Whoops! inside sayHi(), the old name is used! error! +admin.sayHi(); // Whoops! dentro de sayHi(), o nome antigo é utilizado! erro! ``` -If we used `this.name` instead of `user.name` inside the `alert`, then the code would work. +Se empregássemos `this.name` em vez de `user.name` dentro de `alert`, então o código funcionaria. -## "this" is not bound +## "*this*" não está vinculado -In JavaScript, "this" keyword behaves unlike most other programming languages. First, it can be used in any function. +Em JavaScript, a palavra-chave "this" não se comporta como em muitas outras linguagens de programação. Em primeiro lugar, pode ser utilizada em qualquer função. -There's no syntax error in the code like that: +Não existe algum erro de sintaxe num código como este: ```js function sayHi() { @@ -176,9 +176,9 @@ function sayHi() { } ``` -The value of `this` is evaluated during the run-time. And it can be anything. +O valor de `this` é avaliado em tempo de execução. E, pode ser qualquer coisa. -For instance, the same function may have different "this" when called from different objects: +Por exemplo, uma mesma função pode ter diferentes "*this*" quando invocada de diferentes objetos: ```js run let user = { name: "John" }; @@ -189,20 +189,20 @@ function sayHi() { } *!* -// use the same functions in two objects +// use a mesma função em dois objectos user.f = sayHi; admin.f = sayHi; */!* -// these calls have different this -// "this" inside the function is the object "before the dot" +// estas chamadas têm diferentes 'this' +// "this" dentro da função é o objeto "antes do ponto" user.f(); // John (this == user) admin.f(); // Admin (this == admin) -admin['f'](); // Admin (dot or square brackets access the method – doesn't matter) +admin['f'](); // Admin (ponto ou parênteses retos para aceder ao método – é irrelevante) ``` -Actually, we can call the function without an object at all: +Na verdade, podemos invocar a função sem nenhum objeto: ```js run function sayHi() { @@ -212,31 +212,31 @@ function sayHi() { sayHi(); // undefined ``` -In this case `this` is `undefined` in strict mode. If we try to access `this.name`, there will be an error. +Neste caso, `this` está `undefined` no modo estrito (*strict mode*). Se tentarmos aceder a `this.name`, haverá um erro. -In non-strict mode the value of `this` in such case will be the *global object* (`window` in a browser, we'll get to it later in the chapter [](info:global-object)). This is a historical behavior that `"use strict"` fixes. +No modo não-estrito (*non-strict mode*), `this` será o *objeto global* (`window` num *browser*, o que veremos mais adiante no capítulo [Global object](info:global-object). Este, é um procedimento histórico que `"use strict"` corrige. -Please note that usually a call of a function that uses `this` without an object is not normal, but rather a programming mistake. If a function has `this`, then it is usually meant to be called in the context of an object. +Por favor, note que geralmente uma chamada de função que use `this` sem um objeto não é normal, mas sim um erro de programação. Se uma função contiver `this`, então deverá ser invocada no contexto de um objeto. -```smart header="The consequences of unbound `this`" -If you come from another programming language, then you are probably used to the idea of a "bound `this`", where methods defined in an object always have `this` referencing that object. +```smart header="As consequências de 'this' não vinculado" +Se vem de uma outra linguagem de programação, então provavelmente está habituado à ideia de um `this` "vinculado", onde métodos definidos num objeto têm sempre `this` como referência a esse objeto. -In JavaScript `this` is "free", its value is evaluated at call-time and does not depend on where the method was declared, but rather on what's the object "before the dot". +Em JavaScript `this` é "livre", o seu valor é avaliado no momento da invocação (*call-time*) e não depende de onde o método foi declarado, mas sim de qual o objeto "antes do ponto". -The concept of run-time evaluated `this` has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, greater flexibility opens a place for mistakes. +O conceito de `this` avaliado em tempo-de-execução (*run-time*), possui ambas vantagens e desvantagens. Por um lado, uma função pode ser re-utilizada em objetos diferentes. Por outro, uma maior flexibilidade abre espaço para erros. -Here our position is not to judge whether this language design decision is good or bad. We'll understand how to work with it, how to get benefits and evade problems. +Aqui, a nossa posição não é julgar se a decisão no desenho desta linguagem é boa ou má. Iremos compreender como trabalhar com ele, como colher benefícios e como evitar problemas. ``` -## Internals: Reference Type +## Internamente: o Tipo Referência -```warn header="In-depth language feature" -This section covers an advanced topic, to understand certain edge-cases better. +```warn header="Intrínsica funcionalidade da linguagem" +Esta secção cobre um tópico avançado, para uma melhor compreensão de certos casos-limite. -If you want to go on faster, it can be skipped or postponed. +Se quiser avançar mais rapidamente, pode ser saltada ou adiada. ``` -An intricate method call can lose `this`, for instance: +Um método complicado pode perder `this`, por exemplo: ```js run let user = { @@ -245,40 +245,40 @@ let user = { bye() { alert("Bye"); } }; -user.hi(); // John (the simple call works) +user.hi(); // John (a chamada simples funciona) *!* -// now let's call user.hi or user.bye depending on the name -(user.name == "John" ? user.hi : user.bye)(); // Error! +// agora vamos invocar user.hi ou user.bye, dependendo do nome +(user.name == "John" ? user.hi : user.bye)(); // Erro! */!* ``` -On the last line there is a ternary operator that chooses either `user.hi` or `user.bye`. In this case the result is `user.hi`. +Na última linha, existe um operador ternário (*ternary operator*) que permite escolher `user.hi` ou `user.bye`. Para o presente caso, o resultado será `user.hi`. -The method is immediately called with parentheses `()`. But it doesn't work right! +O método é imediatamente chamado com os parênteses `()`. Mas, não funciona corretamente! -You can see that the call results in an error, because the value of `"this"` inside the call becomes `undefined`. +Pode observar que a chamada resulta num erro, porque o valor de `"this"` dentro da chamada torna-se `undefined`. -This works (object dot method): +Isto funciona (objeto ponto método): ```js user.hi(); ``` -This doesn't (evaluated method): +Isto não (método avaliado): ```js -(user.name == "John" ? user.hi : user.bye)(); // Error! +(user.name == "John" ? user.hi : user.bye)(); // Erro! ``` -Why? If we want to understand why it happens, let's get under the hood of how `obj.method()` call works. +Porquê? Se, quisermos compreender porque acontece, vamos analisar como a chamada `obj.method()` funciona. -Looking closely, we may notice two operations in `obj.method()` statement: +Observando mais de perto, podemos notar duas operações na instrução `obj.method()`: -1. First, the dot `'.'` retrieves the property `obj.method`. -2. Then parentheses `()` execute it. +1. Primeiro, o ponto `'.'` obtem a propriedade `obj.method`. +2. Depois, os parênteses `()` a executam. -So, how does the information about `this` get passed from the first part to the second one? +Assim, como a informação sobre `this` passa da primeira parte para segunda? -If we put these operations on separate lines, then `this` will be lost for sure: +Se colocarmos essas operações em linhas separadas, então `this` de certeza será perdido: ```js run let user = { @@ -287,42 +287,42 @@ let user = { } *!* -// split getting and calling the method in two lines +// particione o obter e chamar o método em duas linhas let hi = user.hi; -hi(); // Error, because this is undefined +hi(); // Erro, porque 'this' está undefined */!* ``` -Here `hi = user.hi` puts the function into the variable, and then on the last line it is completely standalone, and so there's no `this`. +Aqui, `hi = user.hi` coloca a função numa variável, e a seguir na última linha ela está completamente isolada, não existe nenhum `this`. -**To make `user.hi()` calls work, JavaScript uses a trick -- the dot `'.'` returns not a function, but a value of the special [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type).** +**Para fazer a chamada `user.hi()` funcionar, JavaScript usa um truque -- o ponto `'.'` não retorna um função , mas um valor especial [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type) (do tipo referência).** -The Reference Type is a "specification type". We can't explicitly use it, but it is used internally by the language. +O *Reference Type* é um "tipo incorporado na especificação". Não o podemos utilizar explicitamente, mas é usado internamente pela linguagem. -The value of Reference Type is a three-value combination `(base, name, strict)`, where: +O valor do *Reference Type* é uma combinação de três-valores `(base, name, strict)`, onde: -- `base` is the object. -- `name` is the property. -- `strict` is true if `use strict` is in effect. +- `base` é o objeto. +- `name` é a propriedade. +- `strict` é *true* (verdadeiro) se `use strict` estiver em efeito. -The result of a property access `user.hi` is not a function, but a value of Reference Type. For `user.hi` in strict mode it is: +O resultado de um acesso à propriedade `user.hi` não é uma função, mas um valor do tipo Referência (*Reference Type*). Para `user.hi` em modo estrito (*strict mode*) ele é: ```js -// Reference Type value +// valor do Tipo Referência (user, "hi", true) ``` -When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this` (`=user` in this case). +Quando parênteses `()` são chamados sobre o *Reference Type*, eles recebem uma completa informação sobre o objeto e o seu método, e pode ser estabelecido o `this` certo (`=user`, neste caso). -Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi` (a function) and passes it on. So any further operation "loses" `this`. +Qualquer outra operação, como a atribuição `hi = user.hi` descarta totalmente o tipo referência, toma o valor de `user.hi` (uma função) e o passa. Assim, qualquer operação posterior "perde" o `this`. -So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj['method']()` syntax (they do the same here). Later in this tutorial, we will learn various ways to solve this problem such as [func.bind()](/bind#solution-2-bind). +Deste modo, como resultado, o valor de `this` apenas é passado da forma correta se a função for chamada diretamente utilizando um ponto `obj.method()` ou a sintaxe de parênteses retos `obj['method']()` (eles fazem o mesmo aqui). Mais adiante neste tutorial, vamos aprender várias formas de resolver este problema, como por exemplo [func.bind()](/bind#solution-2-bind). -## Arrow functions have no "this" +## As funções *arrow* não têm "this" -Arrow functions are special: they don't have their "own" `this`. If we reference `this` from such a function, it's taken from the outer "normal" function. +Funções *arrow* são especiais: elas não possuem o seu "próprio" `this`. Se fizermos referência a `this` dentro de uma tal função, ele é tomado da função externa "normal". -For instance, here `arrow()` uses `this` from the outer `user.sayHi()` method: +Por exemplo, aqui `arrow()` usa o `this` do método externo `user.sayHi()`: ```js run let user = { @@ -336,18 +336,19 @@ let user = { user.sayHi(); // Ilya ``` -That's a special feature of arrow functions, it's useful when we actually do not want to have a separate `this`, but rather to take it from the outer context. Later in the chapter we'll go more deeply into arrow functions. +Essa, é uma particularidade especial das funções *arrow*, e é útil quando na realidade não quisermos ter um `this` em separado, mas apenas o obter do contexto exterior. Mais adiante, no capítulo trataremos com mais pormenor de funções *arrow*. + +## Sumário -## Summary +- Funções que são armazenadas em propriedades de objetos são chamadas de "métodos". +- Métodos permitem a objetos "interagir", como `object.doSomething()`. +- Métodos podem referenciar o objeto por `this`. -- Functions that are stored in object properties are called "methods". -- Methods allow objects to "act" like `object.doSomething()`. -- Methods can reference the object as `this`. +O valor de `this` é definido em tempo-de-execução. -The value of `this` is defined at run-time. -- When a function is declared, it may use `this`, but that `this` has no value until the function is called. -- That function can be copied between objects. -- When a function is called in the "method" syntax: `object.method()`, the value of `this` during the call is `object`. +- Quando uma função é declarada, pode empregar o `this`, mas esse `this` não tem qualquer valor até a função ser chamada. +- Essa função pode ser copiada entre objetos. +- Quando uma função é chamada pela sintaxe de "método" `object.method()`, o valor de `this` durante a chamada é `object`. -Please note that arrow functions are special: they have no `this`. When `this` is accessed inside an arrow function, it is taken from outside. +Por favor, note que funções *arrow* são especiais: elas não possuem `this`. Quando `this` é acedido dentro de uma função *arrow*, o valor é tomado de fora. From 42a1ffa8e167827f5427afdf63eb8bce3c47da1d Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Mon, 14 Sep 2020 23:40:38 +0100 Subject: [PATCH 2/4] Update object 'this'. --- .../2-check-syntax/solution.md | 37 ---- .../04-object-methods/2-check-syntax/task.md | 19 -- .../04-object-methods/3-why-this/solution.md | 21 -- .../04-object-methods/3-why-this/task.md | 25 --- .../4-object-property-this/solution.md | 30 ++- .../4-object-property-this/task.md | 4 +- .../8-chain-calls/_js.view/test.js | 2 +- .../04-object-methods/article.md | 182 +++++------------- 8 files changed, 72 insertions(+), 248 deletions(-) delete mode 100644 1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md delete mode 100644 1-js/04-object-basics/04-object-methods/2-check-syntax/task.md delete mode 100644 1-js/04-object-basics/04-object-methods/3-why-this/solution.md delete mode 100644 1-js/04-object-basics/04-object-methods/3-why-this/task.md diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md deleted file mode 100644 index 3554a5be4..000000000 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md +++ /dev/null @@ -1,37 +0,0 @@ -**Erro**! - -Tente isto: - -```js run -let user = { - name: "John", - go: function() { alert(this.name) } -} - -(user.go)() // erro! -``` - -A mensagem de erro, na maior parte dos navegadores (*browsers*), não nos dá uma compreensão do que ocorre de errado. - -**O erro aparece porque falta um ponto-e-vírgula depois de `user = {...}`.** - -JavaScript não assume um ponto-e-vírgula antes do parêntese de `(user.go)()`, por isso lê o código como: - -```js no-beautify -let user = { go:... }(user.go)() -``` - -Assim, podemos também observar que, tal expressão conjunta é sintáticamente uma chamada do objeto `{ go: ... }` como uma função, tomando `(user.go)` como argumento. E, isso também ocorre na mesma linha que `let user`, então o objeto `user` ainda não foi definido, e por isto o erro. - -Se inserirmos o ponto-e-vírgula, tudo estará bem: - -```js run -let user = { - name: "John", - go: function() { alert(this.name) } -}*!*;*/!* - -(user.go)() // 'John' -``` - -Por favor, note que os parênteses em `(user.go)` nada aqui fazem. Geralmente, eles estabelecem a ordem das operações, mas aqui o ponto `.` já funciona à partida, então não têm efeito algum. Apenas, aquele ponto-e-vírgula importa. diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md deleted file mode 100644 index ef43de48c..000000000 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md +++ /dev/null @@ -1,19 +0,0 @@ -importância: 2 - ---- - -# Verificação sintática - -Qual o resultado deste código? - - -```js no-beautify -let user = { - name: "John", - go: function() { alert(this.name) } -} - -(user.go)() -``` - -P.S. Existe um falha :) diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md b/1-js/04-object-basics/04-object-methods/3-why-this/solution.md deleted file mode 100644 index c48fcdceb..000000000 --- a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md +++ /dev/null @@ -1,21 +0,0 @@ - -Aqui estão as explicações. - -1. É uma regular invocação do método do objeto. - -2. O mesmo. Aqui, os parênteses não alteram a ordem das operações, o ponto já funciona à primeira. - -3. Aqui, temos uma chamada `(expression).method()` mais complexa. A chamada funciona como se fosse particionada em duas linhas: - - ```js no-beautify - f = obj.go; // calcula a expressão - f(); // invoca o resultado - ``` - - Aqui, `f()` é executada como uma função, sem `this`. - -4. Algo similar a `(3)`, à esquerda do ponto `.` temos uma expressão. - -Para explicar o comportamento de `(3)` e `(4)`, recordemo-nos que propriedades acessoras (o ponto ou os parênteses retos) retornam um valor do Tipo *Reference*. - -Qualquer operação com elas (como, atribuição `=` ou `||`), exceto a chamada a um método, o transforma num valor ordinário, o qual não transporta a informação necessária para configurar `this`. diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/task.md b/1-js/04-object-basics/04-object-methods/3-why-this/task.md deleted file mode 100644 index 919f17220..000000000 --- a/1-js/04-object-basics/04-object-methods/3-why-this/task.md +++ /dev/null @@ -1,25 +0,0 @@ -importância: 3 - ---- - -# Explique o valor de "this" - -No código abaixo, pretendemos invocar o método `user.go()` 4 vezes seguidas. - -Mas, as chamadas `(1)` e `(2)` funcionam de forma diferente do que as `(3)` e `(4)`. Porquê? - -```js run no-beautify -let obj, method; - -obj = { - go: function() { alert(this); } -}; - -obj.go(); // (1) [object Object] - -(obj.go)(); // (2) [object Object] - -(method = obj.go)(); // (3) undefined - -(obj.go || obj.stop)(); // (4) undefined -``` diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md index 14f42f296..384eb7e4f 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md @@ -1,6 +1,7 @@ **Resposta: um erro.** Tente isto: + ```js run function makeUser() { return { @@ -12,16 +13,29 @@ function makeUser() { let user = makeUser(); alert( user.ref.name ); // Error: Cannot read property 'name' of undefined - // (Erro: não é possível ler a propriedade 'name' de undefined) +// (Erro: não é possível ler a propriedade 'name' de undefined) ``` -Isto, porque regras que estabelecem `this` não têm em conta objetos literais. +Isto, porque as regras que regulam `this` não olham para a definição do objeto. O que apenas importa é o momento da chamada. + +Aqui, o valor de `this` dentro de `makeUser()` é `undefined`, porque ela é invocada como uma função, não como um método usando a sintaxe com "ponto". + +O valor de `this` é o mesmo para toda uma função, e nem blocos de código nem objetos literais o afetam. + +Assim, na verdade `ref: this` recebe o presente valor `this` da função. + +Podemos reescrever a função, e retornar o mesmo `this` com o valor `undefined`: -Aqui, o valor de `this` dentro de `makeUser()` está `undefined`, porque é invocado como uma função, não como um método. +```js run +function makeUser(){ + return this; // desta vez, não existe um objeto literal +} -E um objeto literal não possui qualquer efeito sobre `this`. O valor de `this` é o mesmo para toda uma função, e tanto blocos de código como objetos literais não exercem qualquer influência sobre ele. +alert( makeUser().name ); // Error: Cannot read property 'name' of undefined +// (Erro: não é possível ler a propriedade 'name' de undefined) +``` -Assim, na realidade `ref: this` recebe o valor atual `this` da função. +Como pode ver, o resultado de `alert( makeUser().name )` é o mesmo que o resultado de `alert( user.ref.name )` no exemplo anterior. Aqui, o caso oposto: @@ -35,13 +49,11 @@ function makeUser() { } */!* }; -}; +} let user = makeUser(); alert( user.ref().name ); // 'John' ``` -Agora funciona, porque `user.ref()` é um método. E, o valor de `this` já é uma referência ao objeto antes do ponto `.`. - - +Agora funciona, porque `user.ref()` é um método. E, o valor de `this` é a referência ao objeto antes do ponto `.`. diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md index 200392df1..1e4384175 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md @@ -6,7 +6,7 @@ importância: 5 Aqui, a função `makeUser` retorna um objeto. -Qual o resultado de aceder à sua `ref`? Porquê? +Qual é o resultado de aceder à sua `ref`? Porquê? ```js function makeUser() { @@ -18,5 +18,5 @@ function makeUser() { let user = makeUser(); -alert( user.ref.name ); // Qual o resultado? +alert( user.ref.name ); // Qual é o resultado? ``` diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js index e9cb1f8de..62ce74b76 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js @@ -1,5 +1,5 @@ -describe('Ladder', function() { +describe('Escada', function() { before(function() { window.alert = sinon.stub(window, "alert"); }); diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 3e6f5ef45..bc28b98ae 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -1,6 +1,6 @@ -# Métodos do objeto, "this" +# Métodos de objetos, "this" -Objectos, geralmente são criados como representação de entidades no mundo real, como utilizadores, encomendas e assim por diante: +Objetos geralmente são criados para representar entidades do mundo real, como utilizadores, encomendas, e assim por diante: ```js let user = { @@ -9,13 +9,13 @@ let user = { }; ``` -E, no mundo real, um utilizador pode *interagir*: selecionar algo de um carrinho de compras, *login*, *logout*, etc. +E no mundo real, um utilizador pode *interagir*: selecionar algo de um carrinho de compras, *login*, *logout*, etc. As interações, são representadas em JavaScript por funções em propriedades. ## Exemplos de métodos -Para começar, ensinemos ao `user` a dizer olá: +Para começar, vamos ensinar ao `user` a dizer olá: ```js run let user = { @@ -32,7 +32,7 @@ user.sayHi = function() { user.sayHi(); // Olá! ``` -Aqui, acabamos de empregar uma Expressão de Função (*Function Expression*) para criar uma função e a atribuir à propriedade do objeto `user.sayHi`. +Aqui, acabamos de usar uma Expressão de Função (*Function Expression*) para criar uma função, e de fazer a sua atribuição à propriedade do objeto `user.sayHi`. Depois, a podemos invocar. O utilizador pode agora falar! @@ -40,7 +40,7 @@ Uma função que seja uma propriedade de um objeto, é chamada de seu *método* Assim, temos o método `sayHi` do objeto `user`. -Evidentemente, poderiamos usar uma função pré-declarada como método. Desta forma: +Evidentemente, poderíamos utilizar uma função pré-declarada como método, desta forma: ```js run let user = { @@ -50,27 +50,28 @@ let user = { *!* // primeiro, declare function sayHi() { - alert("Hello!"); + alert("Olá!"); }; -// Depois adicine como método +// depois adicione como um método user.sayHi = sayHi; */!* -user.sayHi(); // Hello! +user.sayHi(); // Olá! ``` ```smart header="Programação orientada por objetos" -Quando escrevemos o nosso código empregando objetos para representar entidades, é chamada de [Programação orientada a objetos](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_objetos) (*object-oriented programming*), abreviadamente: "OOP". +Quando escrevemos o nosso código empregando objetos para representar entidades, é a chamada [Programação orientada a objetos](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_objetos), abreviadamente: "OOP" (*object-oriented programming*). -OOP (Programação orientada por objetos) é algo grande, uma ciência interessante por si mesma. Como escolher as entidades certas? Como organizar a interação enter elas? É arquitetura, e existem grandes livros neste tópico, como "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides ou "Object-Oriented Analysis and Design with Applications" by G.Booch, e mais. +OOP (Programação orientada por objetos) é algo grande, uma ciência interessante por si mesma. Como escolher as entidades certas? Como organizar a interação entre elas? É arquitetura, e existem grandes livros neste tópico, como "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides, ou "Object-Oriented Analysis and Design with Applications" by G.Booch, e outros. ``` + ### Abreviação de método -Existe uma sintaxe mais curta para métodos num objeto literal: +Existe uma sintaxe mais curta para métodos dentro de um objeto literal: ```js -// estes objetos fazem o mesmo +// ambos os objetos fazem o mesmo let user = { sayHi: function() { @@ -78,7 +79,7 @@ let user = { } }; -// a abreviação de método tem melhor aspeto, não tem? +// a abreviação de método tem um melhor aspeto, não é? let user = { *!* sayHi() { // o mesmo que "sayHi: function()" @@ -94,7 +95,7 @@ Na verdade, as notações não são completamente idênticas. Existem diferença ## "*this*" em métodos -É comum que um método de um objeto precise de aceder à informação armazenada no objeto para executar a sua tarefa. +É comum, que um método de um objeto precise de aceder à informação armazenada no objeto para executar a sua tarefa. Por exemplo, o código dentro de `user.sayHi()` pode precisar do nome do `user`. @@ -122,7 +123,7 @@ user.sayHi(); // John Aqui, durante a execução de `user.sayHi()`, o valor de `this` será `user`. -Tecnicamente, também é possível aceder ao objeto sem `this`, por meio de uma referência numa variável externa: +Tecnicamente, também é possível aceder ao objeto sem `this`, fazendo referência a ele através da variável externa: ```js let user = { @@ -138,7 +139,7 @@ let user = { }; ``` -...Mas tal código não é fiável. Se decidirmos copiar `user` para outra variável, por exemplo `admin = user` e colocar outro valor em `user`, então a cópia irá aceder ao valor errado. +...Mas tal código não é de confiança. Se decidirmos copiar `user` para outra variável, por exemplo `admin = user` e colocar outro valor em `user`, então a cópia irá aceder ao valor errado. Isso, é demonstrado abaixo: @@ -157,18 +158,18 @@ let user = { let admin = user; -user = null; // atribui outro valor, para ser óbvio +user = null; // atribui outro valor, para tornar o processo óbvio -admin.sayHi(); // Whoops! dentro de sayHi(), o nome antigo é utilizado! erro! +admin.sayHi(); // Whoops! dentro de sayHi(), o nome antigo é utilizado! Erro! ``` -Se empregássemos `this.name` em vez de `user.name` dentro de `alert`, então o código funcionaria. +Se tivéssemos usado `this.name` em vez de `user.name` dentro do `alert`, então o código iria funcionar. ## "*this*" não está vinculado -Em JavaScript, a palavra-chave "this" não se comporta como em muitas outras linguagens de programação. Em primeiro lugar, pode ser utilizada em qualquer função. +Em JavaScript, a palavra-chave `this` não se comporta como em muitas outras linguagens de programação. Pode ser utilizada em qualquer função. -Não existe algum erro de sintaxe num código como este: +Não existe nenhum erro de sintaxe no exemplo seguinte: ```js function sayHi() { @@ -176,9 +177,9 @@ function sayHi() { } ``` -O valor de `this` é avaliado em tempo de execução. E, pode ser qualquer coisa. +O valor de `this` é avaliado em tempo de execução, ele depende do contexto. -Por exemplo, uma mesma função pode ter diferentes "*this*" quando invocada de diferentes objetos: +Por exemplo, aqui uma mesma função é atribuída a dois objetos diferentes, então tem "*this*" diferentes nas chamadas: ```js run let user = { name: "John" }; @@ -189,20 +190,23 @@ function sayHi() { } *!* -// use a mesma função em dois objectos +// use a mesma função em dois objetos user.f = sayHi; admin.f = sayHi; */!* -// estas chamadas têm diferentes 'this' -// "this" dentro da função é o objeto "antes do ponto" +// estas chamadas têm 'this' diferentes +// "this" dentro da função, é o objeto "antes do ponto" user.f(); // John (this == user) admin.f(); // Admin (this == admin) admin['f'](); // Admin (ponto ou parênteses retos para aceder ao método – é irrelevante) ``` -Na verdade, podemos invocar a função sem nenhum objeto: +A regra é simples: se é chamado `obj.f()`, então `this` é `obj` durante a chamada de `f`. Deste modo, é `user` ou `admin` no exemplo acima. + +````smart header="Chamando sem um objeto: 'this == undefined'" +Nós até podemos chamar a função sem nenhum objeto: ```js run function sayHi() { @@ -212,115 +216,26 @@ function sayHi() { sayHi(); // undefined ``` -Neste caso, `this` está `undefined` no modo estrito (*strict mode*). Se tentarmos aceder a `this.name`, haverá um erro. +Neste caso `this` é `undefined` no modo estrito (*strict mode*). Se, tentarmos aceder a `this.name` irá ocorrer um erro. -No modo não-estrito (*non-strict mode*), `this` será o *objeto global* (`window` num *browser*, o que veremos mais adiante no capítulo [Global object](info:global-object). Este, é um procedimento histórico que `"use strict"` corrige. +No modo não-estrito, o valor de `this` para este caso será o *objeto global* (`window` num navegador [*browser*], e iremos ver isto mais adiante no capítulo [](info:global-object)). Este, é um comportamento histórico que `"use strict"` corrige. -Por favor, note que geralmente uma chamada de função que use `this` sem um objeto não é normal, mas sim um erro de programação. Se uma função contiver `this`, então deverá ser invocada no contexto de um objeto. +Geralmente, tal chamada é um erro de programação. Se `this` estiver dentro de uma função, ele espera ser chamado no contexto de um objeto. +```` ```smart header="As consequências de 'this' não vinculado" -Se vem de uma outra linguagem de programação, então provavelmente está habituado à ideia de um `this` "vinculado", onde métodos definidos num objeto têm sempre `this` como referência a esse objeto. - -Em JavaScript `this` é "livre", o seu valor é avaliado no momento da invocação (*call-time*) e não depende de onde o método foi declarado, mas sim de qual o objeto "antes do ponto". - -O conceito de `this` avaliado em tempo-de-execução (*run-time*), possui ambas vantagens e desvantagens. Por um lado, uma função pode ser re-utilizada em objetos diferentes. Por outro, uma maior flexibilidade abre espaço para erros. - -Aqui, a nossa posição não é julgar se a decisão no desenho desta linguagem é boa ou má. Iremos compreender como trabalhar com ele, como colher benefícios e como evitar problemas. -``` - -## Internamente: o Tipo Referência - -```warn header="Intrínsica funcionalidade da linguagem" -Esta secção cobre um tópico avançado, para uma melhor compreensão de certos casos-limite. - -Se quiser avançar mais rapidamente, pode ser saltada ou adiada. -``` - -Um método complicado pode perder `this`, por exemplo: - -```js run -let user = { - name: "John", - hi() { alert(this.name); }, - bye() { alert("Bye"); } -}; - -user.hi(); // John (a chamada simples funciona) - -*!* -// agora vamos invocar user.hi ou user.bye, dependendo do nome -(user.name == "John" ? user.hi : user.bye)(); // Erro! -*/!* -``` +Se vem de uma outra linguagem de programação, então provavelmente está habituado à ideia de um "`this` vinculado", onde métodos definidos num objeto têm sempre `this` como referência a esse objeto. -Na última linha, existe um operador ternário (*ternary operator*) que permite escolher `user.hi` ou `user.bye`. Para o presente caso, o resultado será `user.hi`. +Em JavaScript `this` é "livre", o seu valor é avaliado no momento da invocação (*call-time*) e não depende de onde o método foi declarado, mas sim de qual é o objeto "antes do ponto". -O método é imediatamente chamado com os parênteses `()`. Mas, não funciona corretamente! +O conceito de `this` avaliado em tempo-de-execução (*run-time*), possui ambas vantagens e desvantagens. Por um lado, uma função pode ser re-utilizada com objetos diferentes. Por outro, uma maior flexibilidade abre mais espaço para erros. -Pode observar que a chamada resulta num erro, porque o valor de `"this"` dentro da chamada torna-se `undefined`. - -Isto funciona (objeto ponto método): -```js -user.hi(); -``` - -Isto não (método avaliado): -```js -(user.name == "John" ? user.hi : user.bye)(); // Erro! +Aqui, a nossa posição não é julgar se a decisão no desenho desta linguagem é boa ou má. Iremos compreender como trabalhar com ele, como colher benefícios e evitar problemas. ``` -Porquê? Se, quisermos compreender porque acontece, vamos analisar como a chamada `obj.method()` funciona. +## As funções seta não têm "this" -Observando mais de perto, podemos notar duas operações na instrução `obj.method()`: - -1. Primeiro, o ponto `'.'` obtem a propriedade `obj.method`. -2. Depois, os parênteses `()` a executam. - -Assim, como a informação sobre `this` passa da primeira parte para segunda? - -Se colocarmos essas operações em linhas separadas, então `this` de certeza será perdido: - -```js run -let user = { - name: "John", - hi() { alert(this.name); } -} - -*!* -// particione o obter e chamar o método em duas linhas -let hi = user.hi; -hi(); // Erro, porque 'this' está undefined -*/!* -``` - -Aqui, `hi = user.hi` coloca a função numa variável, e a seguir na última linha ela está completamente isolada, não existe nenhum `this`. - -**Para fazer a chamada `user.hi()` funcionar, JavaScript usa um truque -- o ponto `'.'` não retorna um função , mas um valor especial [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type) (do tipo referência).** - -O *Reference Type* é um "tipo incorporado na especificação". Não o podemos utilizar explicitamente, mas é usado internamente pela linguagem. - -O valor do *Reference Type* é uma combinação de três-valores `(base, name, strict)`, onde: - -- `base` é o objeto. -- `name` é a propriedade. -- `strict` é *true* (verdadeiro) se `use strict` estiver em efeito. - -O resultado de um acesso à propriedade `user.hi` não é uma função, mas um valor do tipo Referência (*Reference Type*). Para `user.hi` em modo estrito (*strict mode*) ele é: - -```js -// valor do Tipo Referência -(user, "hi", true) -``` - -Quando parênteses `()` são chamados sobre o *Reference Type*, eles recebem uma completa informação sobre o objeto e o seu método, e pode ser estabelecido o `this` certo (`=user`, neste caso). - -Qualquer outra operação, como a atribuição `hi = user.hi` descarta totalmente o tipo referência, toma o valor de `user.hi` (uma função) e o passa. Assim, qualquer operação posterior "perde" o `this`. - -Deste modo, como resultado, o valor de `this` apenas é passado da forma correta se a função for chamada diretamente utilizando um ponto `obj.method()` ou a sintaxe de parênteses retos `obj['method']()` (eles fazem o mesmo aqui). Mais adiante neste tutorial, vamos aprender várias formas de resolver este problema, como por exemplo [func.bind()](/bind#solution-2-bind). - -## As funções *arrow* não têm "this" - -Funções *arrow* são especiais: elas não possuem o seu "próprio" `this`. Se fizermos referência a `this` dentro de uma tal função, ele é tomado da função externa "normal". +As funções seta (*arrow functions*) são especiais: elas não possuem o seu "próprio" `this`. Se fizermos referência a `this` dentro de uma tal função, ele é tomado da função externa "normal". Por exemplo, aqui `arrow()` usa o `this` do método externo `user.sayHi()`: @@ -336,19 +251,18 @@ let user = { user.sayHi(); // Ilya ``` -Essa, é uma particularidade especial das funções *arrow*, e é útil quando na realidade não quisermos ter um `this` em separado, mas apenas o obter do contexto exterior. Mais adiante, no capítulo trataremos com mais pormenor de funções *arrow*. - +Esta, é uma particularidade especial das funções seta, e é útil quando na realidade não quisermos ter um `this` em separado, mas sómente o obter do contexto exterior. Mais adiante, no capítulo trataremos com mais pormenor de funções seta. ## Sumário - Funções que são armazenadas em propriedades de objetos são chamadas de "métodos". -- Métodos permitem a objetos "interagir", como `object.doSomething()`. +- Métodos permitem "ação" a objetos, como `object.doSomething()`. - Métodos podem referenciar o objeto por `this`. O valor de `this` é definido em tempo-de-execução. -- Quando uma função é declarada, pode empregar o `this`, mas esse `this` não tem qualquer valor até a função ser chamada. -- Essa função pode ser copiada entre objetos. -- Quando uma função é chamada pela sintaxe de "método" `object.method()`, o valor de `this` durante a chamada é `object`. +- Quando uma função é declarada pode utilizar o `this`, mas esse `this` não tem qualquer valor até que a função seja chamada. +- Uma função pode ser copiada entre objetos. +- Quando uma função é invocada pela sintaxe de "método", ex. `object.method()`, o valor de `this` durante a chamada é `object`. -Por favor, note que funções *arrow* são especiais: elas não possuem `this`. Quando `this` é acedido dentro de uma função *arrow*, o valor é tomado de fora. +Por favor, note que funções seta (*arrow functions*) são especiais: elas não possuem `this`. Quando `this` é acedido dentro de uma função seta, o seu valor é tomado de fora. From 20fa4b9614c246c4342bf9e881245b803439ead2 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Tue, 15 Dec 2020 23:51:05 +0100 Subject: [PATCH 3/4] Update "Object ...this" translations. --- .../4-object-property-this/solution.md | 14 ++--- .../4-object-property-this/task.md | 3 +- .../04-object-methods/7-calculator/task.md | 1 + .../8-chain-calls/_js.view/test.js | 2 +- .../8-chain-calls/solution.md | 4 +- .../04-object-methods/8-chain-calls/task.md | 10 ++-- .../04-object-methods/article.md | 52 ++++++++++--------- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md index 384eb7e4f..962db02d1 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md @@ -1,7 +1,6 @@ **Resposta: um erro.** Tente isto: - ```js run function makeUser() { return { @@ -12,8 +11,7 @@ function makeUser() { let user = makeUser(); -alert( user.ref.name ); // Error: Cannot read property 'name' of undefined -// (Erro: não é possível ler a propriedade 'name' de undefined) +alert( user.ref.name ); // Error: Cannot read property 'name' of undefined (Erro: não é possível ler a propriedade 'name' de undefined) ``` Isto, porque as regras que regulam `this` não olham para a definição do objeto. O que apenas importa é o momento da chamada. @@ -24,20 +22,18 @@ O valor de `this` é o mesmo para toda uma função, e nem blocos de código nem Assim, na verdade `ref: this` recebe o presente valor `this` da função. -Podemos reescrever a função, e retornar o mesmo `this` com o valor `undefined`: +Nós podemos reescrever a função, e retornar o mesmo `this` com o valor `undefined`: ```js run function makeUser(){ return this; // desta vez, não existe um objeto literal } -alert( makeUser().name ); // Error: Cannot read property 'name' of undefined -// (Erro: não é possível ler a propriedade 'name' de undefined) +alert( makeUser().name ); // Error: Cannot read property 'name' of undefined (Erro: não é possível ler a propriedade 'name' de undefined) ``` +Como você pode ver, o resultado de `alert( makeUser().name )` é o mesmo que o resultado de `alert( user.ref.name )` no exemplo anterior. -Como pode ver, o resultado de `alert( makeUser().name )` é o mesmo que o resultado de `alert( user.ref.name )` no exemplo anterior. - -Aqui, o caso oposto: +Aqui está o caso oposto: ```js run function makeUser() { diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md index 1e4384175..1900ed239 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md @@ -1,4 +1,4 @@ -importância: 5 +importance: 5 --- @@ -20,3 +20,4 @@ let user = makeUser(); alert( user.ref.name ); // Qual é o resultado? ``` + diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md index acce94c85..a04da7a28 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md @@ -21,3 +21,4 @@ alert( calculator.mul() ); ``` [demo] + diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js index 62ce74b76..75dbde4b8 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js @@ -16,7 +16,7 @@ describe('Escada', function() { assert.equal(ladder.down(), ladder); }); - it('showStep() deveria chamar alert', function() { + it('showStep() deveria invocar alert', function() { ladder.showStep(); assert(alert.called); }); diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index 620384a37..b88ff3738 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -1,4 +1,4 @@ -A solução será retornar o próprio objeto em cada chamada. +A solução será retornar o próprio objeto em cada invocação. ```js execute demo let ladder = { @@ -26,7 +26,7 @@ let ladder = { ladder.up().up().down().up().down().showStep(); // 1 ``` -Podemos também escrever uma única chamada por linha. Para longas cadeias é mais legível: +Nós também podemos escrever uma única invocação por linha. Para longas cadeias é mais legível: ```js ladder diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md index 8c38cbe9c..0906e075d 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md @@ -1,4 +1,4 @@ -importância: 2 +importance: 2 --- @@ -9,19 +9,19 @@ Existe um objeto `ladder` (escada) que permite subir e descer: ```js let ladder = { step: 0, - up() { + up() { this.step++; }, - down() { + down() { this.step--; }, - showStep: function() { // mostra o atual degrau + showStep: function() { // mostra o degrau atual alert( this.step ); } }; ``` -Agora, se precisarmos de fazer várias chamadas em sequência, podemos fazê-las desta forma: +Agora, se precisarmos de fazer várias chamadas em sequência, podemos as efetuar desta forma: ```js ladder.up(); diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index bc28b98ae..512dc0d87 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -9,7 +9,7 @@ let user = { }; ``` -E no mundo real, um utilizador pode *interagir*: selecionar algo de um carrinho de compras, *login*, *logout*, etc. +E no mundo real, um utilizador pode *interagir*: selecionar algo de um carrinho de compras, fazer *login*, *logout*, etc. As interações, são representadas em JavaScript por funções em propriedades. @@ -32,15 +32,15 @@ user.sayHi = function() { user.sayHi(); // Olá! ``` -Aqui, acabamos de usar uma Expressão de Função (*Function Expression*) para criar uma função, e de fazer a sua atribuição à propriedade do objeto `user.sayHi`. +Aqui, acabamos de usar uma Function Expression (*Expressão de Função*) para criar uma função, e de fazer a sua atribuição à propriedade do objeto `user.sayHi`. -Depois, a podemos invocar. O utilizador pode agora falar! +A seguir, a podemos invocar como `user.sayHi()`. O utilizador pode agora falar! Uma função que seja uma propriedade de um objeto, é chamada de seu *método* (*method*). Assim, temos o método `sayHi` do objeto `user`. -Evidentemente, poderíamos utilizar uma função pré-declarada como método, desta forma: +É claro que poderíamos utilizar uma função pré-declarada como método, desta forma: ```js run let user = { @@ -61,14 +61,13 @@ user.sayHi(); // Olá! ``` ```smart header="Programação orientada por objetos" -Quando escrevemos o nosso código empregando objetos para representar entidades, é a chamada [Programação orientada a objetos](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_objetos), abreviadamente: "OOP" (*object-oriented programming*). +Quando escrevemos o nosso código empregando objetos para representar entidades, isto se chama [Programação orientada a objetos](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_objetos), abreviadamente: "OOP" (*object-oriented programming*). -OOP (Programação orientada por objetos) é algo grande, uma ciência interessante por si mesma. Como escolher as entidades certas? Como organizar a interação entre elas? É arquitetura, e existem grandes livros neste tópico, como "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides, ou "Object-Oriented Analysis and Design with Applications" by G.Booch, e outros. +OOP (Programação orientada por objetos) é algo grande, uma ciência interessante por si mesma. Como escolher as entidades certas? Como organizar a interação entre elas? É arquitetura, e existem bons livros neste tópico, como "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides, ou "Object-Oriented Analysis and Design with Applications" by G.Booch, e outros. ``` - ### Abreviação de método -Existe uma sintaxe mais curta para métodos dentro de um objeto literal: +Há uma sintaxe mais curta para métodos dentro de um objeto literal: ```js // ambos os objetos fazem o mesmo @@ -91,7 +90,7 @@ let user = { Como demonstrado, podemos omitir `"function"` e apenas escrever `sayHi()`. -Na verdade, as notações não são completamente idênticas. Existem diferenças subtis em relação à herança do objeto (a ser estudado mais adiante), mas por ora elas não interessam. Em quase todos os casos, a sintaxe mais curta é preferível. +Na verdade, as notações não são totalmente idênticas. Existem diferenças subtis relacionadas com a herança do objeto (a ser estudado mais adiante), mas por ora elas não interessam. Em quase todos os casos, a sintaxe mais curta é preferível. ## "*this*" em métodos @@ -112,6 +111,7 @@ let user = { sayHi() { *!* + // "this" é o objeto atual alert(this.name); */!* } @@ -121,7 +121,7 @@ let user = { user.sayHi(); // John ``` -Aqui, durante a execução de `user.sayHi()`, o valor de `this` será `user`. +Aqui, durante a execução de `user.sayHi()`, o valor de `this` é `user`. Tecnicamente, também é possível aceder ao objeto sem `this`, fazendo referência a ele através da variável externa: @@ -139,7 +139,7 @@ let user = { }; ``` -...Mas tal código não é de confiança. Se decidirmos copiar `user` para outra variável, por exemplo `admin = user` e colocar outro valor em `user`, então a cópia irá aceder ao valor errado. +...Mas tal código não é fiável. Se decidirmos copiar `user` para outra variável, por exemplo `admin = user` e colocar um valor diferente em `user`, então a cópia irá aceder ao valor errado. Isso, é demonstrado abaixo: @@ -160,14 +160,16 @@ let user = { let admin = user; user = null; // atribui outro valor, para tornar o processo óbvio -admin.sayHi(); // Whoops! dentro de sayHi(), o nome antigo é utilizado! Erro! +*!* +admin.sayHi(); // TypeError: Cannot read property 'name' of null (ErroDeTipo: Não é possível ler a propriedade 'name' de null) +*/!* ``` Se tivéssemos usado `this.name` em vez de `user.name` dentro do `alert`, então o código iria funcionar. ## "*this*" não está vinculado -Em JavaScript, a palavra-chave `this` não se comporta como em muitas outras linguagens de programação. Pode ser utilizada em qualquer função. +Em JavaScript, a palavra-chave `this` não se comporta como em muitas outras linguagens de programação. Ela pode ser utilizada em qualquer função, mesmo que a função não seja um método de um objeto. Não existe nenhum erro de sintaxe no exemplo seguinte: @@ -179,7 +181,7 @@ function sayHi() { O valor de `this` é avaliado em tempo de execução, ele depende do contexto. -Por exemplo, aqui uma mesma função é atribuída a dois objetos diferentes, então tem "*this*" diferentes nas chamadas: +Por exemplo, aqui uma mesma função é atribuída a dois objetos diferentes, então tem "*this*" diferentes nas invocações: ```js run let user = { name: "John" }; @@ -196,11 +198,11 @@ admin.f = sayHi; */!* // estas chamadas têm 'this' diferentes -// "this" dentro da função, é o objeto "antes do ponto" +// o "this" dentro da função, é o objeto "antes do ponto" user.f(); // John (this == user) admin.f(); // Admin (this == admin) -admin['f'](); // Admin (ponto ou parênteses retos para aceder ao método – é irrelevante) +admin['f'](); // Admin (ponto ou parênteses retos para se aceder ao método – tanto faz) ``` A regra é simples: se é chamado `obj.f()`, então `this` é `obj` durante a chamada de `f`. Deste modo, é `user` ou `admin` no exemplo acima. @@ -218,24 +220,24 @@ sayHi(); // undefined Neste caso `this` é `undefined` no modo estrito (*strict mode*). Se, tentarmos aceder a `this.name` irá ocorrer um erro. -No modo não-estrito, o valor de `this` para este caso será o *objeto global* (`window` num navegador [*browser*], e iremos ver isto mais adiante no capítulo [](info:global-object)). Este, é um comportamento histórico que `"use strict"` corrige. +No modo não-estrito, o valor de `this` para este caso irá ser o *objeto global* (`window` num navegador, e iremos ver isto mais adiante no capítulo [](info:global-object)). Este é um comportamento histórico que `"use strict"` corrige. Geralmente, tal chamada é um erro de programação. Se `this` estiver dentro de uma função, ele espera ser chamado no contexto de um objeto. ```` ```smart header="As consequências de 'this' não vinculado" -Se vem de uma outra linguagem de programação, então provavelmente está habituado à ideia de um "`this` vinculado", onde métodos definidos num objeto têm sempre `this` como referência a esse objeto. +Se você vem de uma outra linguagem de programação, então provavelmente está habituado à ideia de um "`this` vinculado", onde métodos definidos num objeto têm sempre `this` como referência a esse objeto. -Em JavaScript `this` é "livre", o seu valor é avaliado no momento da invocação (*call-time*) e não depende de onde o método foi declarado, mas sim de qual é o objeto "antes do ponto". +Em JavaScript `this` é "livre", o seu valor é avaliado no momento da invocação (*call-time*) e não depende da altura em que o método foi declarado, mas sim de qual é o objeto "antes do ponto". -O conceito de `this` avaliado em tempo-de-execução (*run-time*), possui ambas vantagens e desvantagens. Por um lado, uma função pode ser re-utilizada com objetos diferentes. Por outro, uma maior flexibilidade abre mais espaço para erros. +O conceito de `this` avaliado em tempo-de-execução (*run-time*), possui ambas vantagens e desvantagens. Por um lado, uma função pode ser re-utilizada em objetos diferentes. Por outro, uma maior flexibilidade abre mais espaço para erros. Aqui, a nossa posição não é julgar se a decisão no desenho desta linguagem é boa ou má. Iremos compreender como trabalhar com ele, como colher benefícios e evitar problemas. ``` -## As funções seta não têm "this" +## *Arrow functions* não têm "this" -As funções seta (*arrow functions*) são especiais: elas não possuem o seu "próprio" `this`. Se fizermos referência a `this` dentro de uma tal função, ele é tomado da função externa "normal". +Arrow functions (*funções seta*) são especiais: elas não possuem o seu "próprio" `this`. Se fizermos referência a `this` dentro de uma tal função, ele é tomado da função externa "normal". Por exemplo, aqui `arrow()` usa o `this` do método externo `user.sayHi()`: @@ -251,16 +253,16 @@ let user = { user.sayHi(); // Ilya ``` -Esta, é uma particularidade especial das funções seta, e é útil quando na realidade não quisermos ter um `this` em separado, mas sómente o obter do contexto exterior. Mais adiante, no capítulo trataremos com mais pormenor de funções seta. +Esta, é uma particularidade especial das funções seta, e é útil quando na realidade não queremos ter um `this` separado, mas simplesmente o obter do contexto exterior. Mais adiante, no capítulo trataremos em mais pormenor de funções seta. + ## Sumário - Funções que são armazenadas em propriedades de objetos são chamadas de "métodos". -- Métodos permitem "ação" a objetos, como `object.doSomething()`. +- Métodos permitem aos objetos "agir", como `object.doSomething()`. - Métodos podem referenciar o objeto por `this`. O valor de `this` é definido em tempo-de-execução. - - Quando uma função é declarada pode utilizar o `this`, mas esse `this` não tem qualquer valor até que a função seja chamada. - Uma função pode ser copiada entre objetos. - Quando uma função é invocada pela sintaxe de "método", ex. `object.method()`, o valor de `this` durante a chamada é `object`. From 5fb93f062e905d2093e3239d55b511ac1b62a889 Mon Sep 17 00:00:00 2001 From: Osvaldo Dias dos Santos Date: Wed, 16 Dec 2020 11:07:14 +0100 Subject: [PATCH 4/4] Remove " ```js ... " translation. --- .../04-object-basics/04-object-methods/7-calculator/solution.md | 2 +- .../04-object-methods/8-chain-calls/solution.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md index b604c3c9c..459997624 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md @@ -1,5 +1,5 @@ -```js execute a solução demo +```js run demo solution let calculator = { sum() { return this.a + this.b; diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index b88ff3738..f18a27ebc 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -1,6 +1,6 @@ A solução será retornar o próprio objeto em cada invocação. -```js execute demo +```js run demo let ladder = { step: 0, up() {