Skip to content

Object methods, "this" #176

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
**Answer: an error.**
**Resposta: um erro.**

Try it:
Tente isto:
```js run
function makeUser() {
return {
name: "John",
ref: this
};
}
};

let user = makeUser();

alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
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 definition. Only the moment of call matters.
Isto, porque as regras que regulam `this` não olham para a definição do objeto. O que apenas importa é o momento da chamada.

Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method with "dot" syntax.
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".

The value of `this` is one for the whole function, code blocks and object literals do not affect it.
O valor de `this` é o mesmo para toda uma função, e nem blocos de código nem objetos literais o afetam.

So `ref: this` actually takes current `this` of the function.
Assim, na verdade `ref: this` recebe o presente valor `this` da função.

We can rewrite the function and return the same `this` with `undefined` value:
Nós podemos reescrever a função, e retornar o mesmo `this` com o valor `undefined`:

```js run
function makeUser(){
return this; // this time there's no object literal
return this; // desta vez, não existe um objeto literal
}

alert( makeUser().name ); // Error: Cannot read property 'name' of undefined
alert( makeUser().name ); // Error: Cannot read property 'name' of undefined (Erro: não é possível ler a propriedade 'name' de undefined)
```
As you can see the result of `alert( makeUser().name )` is the same as the result of `alert( user.ref.name )` from the previous example.
Como você pode ver, o resultado de `alert( makeUser().name )` é o mesmo que o resultado de `alert( user.ref.name )` no exemplo anterior.

Here's the opposite case:
Aqui está o caso oposto:

```js run
function makeUser() {
Expand All @@ -49,7 +49,7 @@ 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` é a referência ao objeto antes do ponto `.`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 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() {
Expand All @@ -18,6 +18,6 @@ function makeUser() {

let user = makeUser();

alert( user.ref.name ); // What's the result?
alert( user.ref.name ); // Qual é o resultado?
```

Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -21,11 +21,11 @@ describe("calculator", function() {
assert.equal(calculator.b, 3);
});

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);
});
});
Expand Down
14 changes: 7 additions & 7 deletions 1-js/04-object-basics/04-object-methods/7-calculator/task.md
Original file line number Diff line number Diff line change
@@ -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 with names `a` and `b` respectively.
- `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 com os nomes `a` e `b` respetivamente.
- `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();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

describe('Ladder', function() {
describe('Escada', function() {
before(function() {
window.alert = sinon.stub(window, "alert");
});
Expand All @@ -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 invocar 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);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The solution is to return the object itself from every call.
A solução será retornar o próprio objeto em cada invocação.

```js run demo
let ladder = {
Expand Down Expand Up @@ -26,7 +26,7 @@ let ladder = {
ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
```

We also can write a single call per line. For long chains it's more readable:
Nós também podemos escrever uma única invocação por linha. Para longas cadeias é mais legível:

```js
ladder
Expand Down
16 changes: 8 additions & 8 deletions 1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ importance: 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 = {
step: 0,
up() {
up() {
this.step++;
},
down() {
down() {
this.step--;
},
showStep: function() { // shows the current step
showStep: function() { // mostra o degrau atual
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 as efetuar desta forma:

```js
ladder.up();
Expand All @@ -32,10 +32,10 @@ ladder.down();
ladder.showStep(); // 0
```

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().down().showStep(); // shows 1 then 0
```

Such approach is widely used across JavaScript libraries.
Tal abordagem é amplamente utilizada em bibliotecas (*libraries*) de JavaScript.
Loading