Skip to content
Open
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,6 +1,6 @@
**Answer: an error.**
**Trả lời: có lỗi.**

Try it:
Hãy thử nó:
```js run
function makeUser() {
return {
Expand All @@ -14,26 +14,26 @@ let user = makeUser();
alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
```

That's because rules that set `this` do not look at object definition. Only the moment of call matters.
Đó là bởi vì các quy tắc đặt `this` không nhìn vào định nghĩa đối tượng. Chỉ có thời điểm sử dụng mới là quan trọng.

Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method with "dot" syntax.
Ở đây, giá trị của `this` bên trong `makeUser()` `undefined`, bởi vì nó được gọi dưới dạng một hàm, không phải dưới dạng một phương thức có cú pháp "dấu chấm".

The value of `this` is one for the whole function, code blocks and object literals do not affect it.
Giá trị của `this` là một cho toàn bộ hàm, các khối mã và các object literal không ảnh hưởng đến giá trị đó.

So `ref: this` actually takes current `this` of the function.
Vì vậy, `ref: this` thực sự lấy `this` hiện tại của hàm.

We can rewrite the function and return the same `this` with `undefined` value:
Chúng ta có thể viết lại hàm và trả về cùng giá trị `this` với giá trị `undefined`:

```js run
function makeUser(){
return this; // this time there's no object literal
return this; // lần này không có đối tượng theo nghĩa đen
}

alert( makeUser().name ); // Error: Cannot read property 'name' of 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.
Như bạn có thể thấy kết quả của `alert( makeUser().name )` giống với kết quả của `alert( user.ref.name )` trong ví dụ trước.

Here's the opposite case:
Đây là trường hợp ngược lại:

```js run
function makeUser() {
Expand All @@ -52,4 +52,4 @@ let user = makeUser();
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 `.`.
Bây giờ nó hoạt động, bởi vì `user.ref()` là một phương thức. Và giá trị của `this` được đặt cho đối tượng trước dấu chấm `.`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Using "this" in object literal
# Sử dụng "this" trong nghĩa đen của đối tượng

Here the function `makeUser` returns an object.
Ở đây hàm `makeUser` trả về một đối tượng.

What is the result of accessing its `ref`? Why?
Kết quả của việc truy cập `ref` của nó là gì? Tại sao?

```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 ); // Kết quả là gì?
```

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@


describe("calculator", function() {
describe("máy tính", function() {

context("when 2 and 3 entered", function() {
context("khi 2 3 được nhập vảo", function() {
beforeEach(function() {
sinon.stub(window, "prompt");
sinon.stub(window, "nhắc");

prompt.onCall(0).returns("2");
prompt.onCall(1).returns("3");
Expand All @@ -16,16 +16,16 @@ describe("calculator", function() {
prompt.restore();
});

it('the read get two values and saves them as object properties', function () {
it('đọc nhận hai giá trị và lưu chúng dưới dạng thuộc tính đối tượng', function () {
assert.equal(calculator.a, 2);
assert.equal(calculator.b, 3);
});

it("the sum is 5", function() {
it("tổng là 5", function() {
assert.equal(calculator.sum(), 5);
});

it("the multiplication product is 6", function() {
it("tích của phép nhân là 6", function() {
assert.equal(calculator.mul(), 6);
});
});
Expand Down
13 changes: 6 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
Expand Up @@ -2,17 +2,17 @@ importance: 5

---

# Create a calculator
# Tạo ra một máy tính

Create an object `calculator` with three methods:
Tạo một đối tượng `máy tính` bằng ba phương thức:

- `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()` nhắc nhập hai giá trị và lưu chúng dưới dạng thuộc tính đối tượng với tên `a` và `b` tương ứng.
- `sum()` trả về tổng các giá trị đã lưu.
- `mul()` nhân các giá trị đã lưu và trả về kết quả.

```js
let calculator = {
// ... your code ...
// ... mã của bạn ...
};

calculator.read();
Expand All @@ -21,4 +21,3 @@ alert( calculator.mul() );
```

[demo]

Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ let ladder = {
},
showStep: function() {
alert(this.step);
return this;
}
};
};
Original file line number Diff line number Diff line change
@@ -1,38 +1,46 @@

describe('Ladder', function() {
describe('Thang', function() {
before(function() {
window.alert = sinon.stub(window, "alert");
window.alert = sinon.stub(window, "nhắc");
});

beforeEach(function() {
ladder.step = 0;
});

it('up() should return this', function() {
it('up() nên trả về cái này', function() {
assert.equal(ladder.up(), ladder);
});

it('down() should return this', function() {
it('down() nên trả về cái này', function() {
assert.equal(ladder.down(), ladder);
});

it('showStep() should call alert', function() {
it('showStep() nên gọi alert', function() {
ladder.showStep();
assert(alert.called);
});

it('up() should increase step', function() {
it('up() nên tăng số bước', function() {
assert.equal(ladder.up().up().step, 2);
});

it('down() should decrease step', function() {
it('down() nên giảm số bước', function() {
assert.equal(ladder.down().step, -1);
});

it('down().up().up().up() ', function() {
assert.equal(ladder.down().up().up().up().step, 2);
});

it('showStep() nên trả về cái này', function() {
assert.equal(ladder.showStep(), ladder);
});

it('up().up().down().showStep().down().showStep()', function () {
assert.equal(ladder.up().up().down().showStep().down().showStep().step, 0)
});

after(function() {
ladder.step = 0;
alert.restore();
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.
Giải pháp là trả lại chính đối tượng đó từ mọi cuộc gọi.

```js run demo
let ladder = {
Expand All @@ -23,10 +23,10 @@ let ladder = {
}
};

ladder.up().up().down().up().down().showStep(); // 1
ladder.up().up().down().showStep().down().showStep(); // hiện 1 rồi 0
```

We also can write a single call per line. For long chains it's more readable:
Chúng ta cũng có thể viết một cuộc gọi trên mỗi dòng. Đối với chuỗi dài, nó dễ đọc hơn:

```js
ladder
Expand Down
16 changes: 9 additions & 7 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,9 +2,9 @@ importance: 2

---

# Chaining
# Kết nối

There's a `ladder` object that allows to go up and down:
Có một đối tượng `ladder` cho phép đi lên và đi xuống:

```js
let ladder = {
Expand All @@ -15,25 +15,27 @@ let ladder = {
down() {
this.step--;
},
showStep: function() { // shows the current step
showStep: function() { // hiển thị bước hiện tại
alert( this.step );
}
};
```

Now, if we need to make several calls in sequence, can do it like this:
Bây giờ, nếu chúng ta cần thực hiện một số cuộc gọi theo trình tự, có thể thực hiện như sau:

```js
ladder.up();
ladder.up();
ladder.down();
ladder.showStep(); // 1
ladder.down();
ladder.showStep(); // 0
```

Modify the code of `up`, `down` and `showStep` to make the calls chainable, like this:
Sửa đổi mã của `up`, `down` `showStep` để thực hiện các cuộc gọi có thể kết nối được, như thế này:

```js
ladder.up().up().down().showStep(); // 1
ladder.up().up().down().showStep().down().showStep(); // hiện 1 rồi 0
```

Such approach is widely used across JavaScript libraries.
Cách tiếp cận như vậy được sử dụng rộng rãi trên các thư viện JavaScript.
Loading