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 f33c9310e..b90fd3d7b 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.** +**Trả lời: có lỗi.** -Try it: +Hãy thử nó: ```js run function makeUser() { return { @@ -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()` là `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() { @@ -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 `.`. 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 c6f8f9658..c48463984 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 @@ -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() { @@ -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ì? ``` 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 4decb76dc..f40c810e8 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 @@ -1,10 +1,10 @@ -describe("calculator", function() { +describe("máy tính", function() { - context("when 2 and 3 entered", function() { + context("khi 2 và 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"); @@ -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); }); }); 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..fe29cc3ac 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 @@ -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(); @@ -21,4 +21,3 @@ alert( calculator.mul() ); ``` [demo] - diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js index e98fe6410..ba6247780 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js @@ -11,5 +11,6 @@ let ladder = { }, showStep: function() { alert(this.step); + return this; } -}; \ No newline at end of file +}; 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..2b0bb222f 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,31 +1,31 @@ -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); }); @@ -33,6 +33,14 @@ describe('Ladder', 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(); 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 ab4e37340..0047880c6 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 @@ -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 = { @@ -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 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..4b971f3e2 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 @@ -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 = { @@ -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` và `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. 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 0d3c1f392..f4115faaf 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" +# Các phương thức đối tượng, "this" -Objects are usually created to represent entities of the real world, like users, orders and so on: +Các đối tượng thường được tạo để đại diện cho các thực thể của thế giới thực, như người dùng, đơn đặt hàng, v.v.: ```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. +Và, trong thế giới thực, người dùng có thể *hành động*: chọn thứ gì đó từ giỏ hàng, đăng nhập, đăng xuất, v.v. -Actions are represented in JavaScript by functions in properties. +Các hành động được thể hiện trong JavaScript bằng các hàm trong thuộc tính. -## Method examples +## Các ví dụ về phương thức -For a start, let's teach the `user` to say hello: +Để bắt đầu, hãy dạy `user` nói xin chào: ```js run let user = { @@ -25,22 +25,22 @@ let user = { *!* user.sayHi = function() { - alert("Hello!"); + alert("Xin chào!"); }; */!* -user.sayHi(); // Hello! +user.sayHi(); // Xin chào! ``` -Here we've just used a Function Expression to create a function and assign it to the property `user.sayHi` of the object. +Ở đây chúng ta vừa sử dụng một Function Expression để tạo một hàm và gán nó cho thuộc tính `user.sayHi` của đối tượng. -Then we can call it as `user.sayHi()`. The user can now speak! +Sau đó, chúng ta có thể gọi nó là `user.sayHi()`. Người dùng bây giờ có thể nói! -A function that is a property of an object is called its *method*. +Hàm là thuộc tính của một đối tượng được gọi là *phương thức* của nó. -So, here we've got a method `sayHi` of the object `user`. +Vì vậy, ở đây chúng ta có một phương thức `sayHi` của đối tượng `user`. -Of course, we could use a pre-declared function as a method, like this: +Tất nhiên, chúng ta có thể sử dụng một hàm được khai báo trước như một phương thức, như sau: ```js run let user = { @@ -48,61 +48,61 @@ let user = { }; *!* -// first, declare +// đầu tiên, khai báo function sayHi() { - alert("Hello!"); -}; + alert("Xin chào!"); +} -// then add as a method +// sau đó thêm như một phương thức user.sayHi = sayHi; */!* -user.sayHi(); // Hello! +user.sayHi(); // Xin chào! ``` -```smart header="Object-oriented programming" -When we write our code using objects to represent entities, that's called [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP". +```smart header="Lập trình hướng đối tượng" +Khi chúng ta viết mã bằng cách sử dụng các đối tượng để biểu diễn các thực thể, điều đó được gọi là [lập trình hướng đối tượng](https://vi.wikipedia.org/wiki/Lập_trình_hướng_đối_tượng), nói ngắn gọn trong tiếng Anh: "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 là một vấn đề lớn, một môn khoa học thú vị của riêng nó. Làm thế nào để chọn đúng thực thể? Làm thế nào để tổ chức sự tương tác giữa chúng? Đó là kiến trúc, và có những cuốn sách hay về chủ đề đó, như "Design Patterns: Elements of Reusable Object-Oriented Software" của E. Gamma, R. Helm, R. Johnson, J. Vissides hoặc "Object-Oriented Analysis and Design with Applications" của G. Booch, và còn nhiều hơn thế nữa. ``` -### Method shorthand +### Phương pháp tốc ký -There exists a shorter syntax for methods in an object literal: +Tồn tại một cú pháp ngắn hơn cho các phương thức trong một đối tượng theo nghĩa đen: ```js -// these objects do the same +// các đối tượng này làm tương tự user = { sayHi: function() { - alert("Hello"); + alert("Xin chào"); } }; -// method shorthand looks better, right? +// phương pháp tốc ký có vẻ tốt hơn, phải không? user = { *!* - sayHi() { // same as "sayHi: function()" + sayHi() { // giống như "sayHi: function(){...}" */!* - alert("Hello"); + alert("Xin chào"); } }; ``` -As demonstrated, we can omit `"function"` and just write `sayHi()`. +Như đã minh họa, chúng ta có thể bỏ qua `"function"` và chỉ cần viết `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. +Nói thật, các ký hiệu không hoàn toàn giống nhau. Có những khác biệt tinh tế liên quan đến kế thừa đối tượng (sẽ được đề cập sau), nhưng hiện tại chúng không quan trọng. Trong hầu hết các trường hợp, cú pháp ngắn hơn được ưa thích hơn. -## "this" in methods +## "this" trong các phương thức -It's common that an object method needs to access the information stored in the object to do its job. +Thông thường, một phương thức đối tượng cần truy cập thông tin được lưu trữ trong đối tượng để thực hiện công việc của nó. -For instance, the code inside `user.sayHi()` may need the name of the `user`. +Chẳng hạn, mã bên trong `user.sayHi()` có thể cần tên của `user`. -**To access the object, a method can use the `this` keyword.** +**Để truy cập đối tượng, một phương thức có thể sử dụng từ khóa `this`.** -The value of `this` is the object "before dot", the one used to call the method. +Giá trị của `this` là đối tượng "trước dấu chấm", đối tượng được sử dụng để gọi phương thức. -For instance: +Ví dụ: ```js run let user = { @@ -111,7 +111,7 @@ let user = { sayHi() { *!* - // "this" is the "current object" + // "this" là "đối tượng hiện tại" alert(this.name); */!* } @@ -121,9 +121,9 @@ let user = { user.sayHi(); // John ``` -Here during the execution of `user.sayHi()`, the value of `this` will be `user`. +Ở đây, trong quá trình thực thi `user.sayHi()`, giá trị của `this` sẽ là `user`. -Technically, it's also possible to access the object without `this`, by referencing it via the outer variable: +Về mặt kỹ thuật, bạn cũng có thể truy cập đối tượng mà không cần `this`, bằng cách tham chiếu nó qua biến bên ngoài: ```js let user = { @@ -132,16 +132,16 @@ let user = { sayHi() { *!* - alert(user.name); // "user" instead of "this" + alert(user.name); // "user" thay vì "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. +...Nhưng mã như vậy là không đáng tin cậy. Nếu chúng ta quyết định sao chép `user` sang một biến khác, ví dụ: `admin = user` và ghi đè `user` bằng thứ khác, thì nó sẽ truy cập sai đối tượng. -That's demonstrated below: +Điều đó được chứng minh dưới đây: ```js run let user = { @@ -150,7 +150,7 @@ let user = { sayHi() { *!* - alert( user.name ); // leads to an error + alert( user.name ); // dẫn đến một lỗi */!* } @@ -158,20 +158,20 @@ let user = { let admin = user; -user = null; // overwrite to make things obvious +user = null; // ghi đè lên để làm cho mọi thứ rõ ràng *!* admin.sayHi(); // TypeError: Cannot read property 'name' of null */!* ``` -If we used `this.name` instead of `user.name` inside the `alert`, then the code would work. +Nếu chúng ta sử dụng `this.name` thay vì `user.name` bên trong `alert` thì mã sẽ hoạt động. -## "this" is not bound +## "this" không bị ràng buộc -In JavaScript, keyword `this` behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object. +Trong JavaScript, từ khóa `this` hoạt động không giống hầu hết các ngôn ngữ lập trình khác. Nó có thể được sử dụng trong bất kỳ hàm nào, ngay cả khi nó không phải là phương thức của đối tượng. -There's no syntax error in the following example: +Không có lỗi cú pháp trong ví dụ sau: ```js function sayHi() { @@ -179,9 +179,9 @@ function sayHi() { } ``` -The value of `this` is evaluated during the run-time, depending on the context. +Giá trị của `this` được đánh giá trong thời gian chạy, tùy thuộc vào ngữ cảnh. -For instance, here the same function is assigned to two different objects and has different "this" in the calls: +Chẳng hạn, ở đây, cùng một hàm được gán cho hai đối tượng khác nhau và có "this" khác nhau trong các lệnh gọi: ```js run let user = { name: "John" }; @@ -192,23 +192,23 @@ function sayHi() { } *!* -// use the same function in two objects +// sử dụng cùng một hàm trong hai đối tượng user.f = sayHi; admin.f = sayHi; */!* -// these calls have different this -// "this" inside the function is the object "before the dot" +// những lần gọi này có this khác nhau +// "this" bên trong hàm là đối tượng "trước dấu chấm" 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 (dấu chấm hoặc dấu ngoặc vuông truy cập phương thức – không quan trọng) ``` -The rule is simple: if `obj.f()` is called, then `this` is `obj` during the call of `f`. So it's either `user` or `admin` in the example above. +Quy tắc rất đơn giản: nếu `obj.f()` được gọi, thì `this` là `obj` trong khi gọi `f`. Vì vậy, đó là `user` hoặc `admin` trong ví dụ trên. -````smart header="Calling without an object: `this == undefined`" -We can even call the function without an object at all: +````smart header="Gọi mà không có đối tượng: `this == undefined`" +Chúng ta thậm chí có thể gọi hàm mà không có đối tượng nào cả: ```js run function sayHi() { @@ -218,28 +218,28 @@ 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. +Trong trường hợp này, `this` là `undefined` ở chế độ nghiêm ngặt. Nếu chúng ta cố gắng truy cập `this.name`, sẽ có lỗi. -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. +Ở chế độ không nghiêm ngặt, giá trị của `this` trong trường hợp này sẽ là *đối tượng chung* (`window` trong trình duyệt, chúng ta sẽ tìm hiểu về nó sau trong chương [](info:global-object)). Đây là một hành vi lịch sử mà `"use strict"` sửa chữa. -Usually such call is a programming error. If there's `this` inside a function, it expects to be called in an object context. +Thông thường cuộc gọi như vậy là một lỗi lập trình. Nếu có `this` bên trong một hàm, thì hàm này sẽ được gọi trong ngữ cảnh đối tượng. ```` -```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="Hậu quả của `this`" không liên kết +Nếu bạn đến từ một ngôn ngữ lập trình khác, thì có lẽ bạn đã quen với ý tưởng về một "`this` bị ràng buộc", trong đó các phương thức được định nghĩa trong một đối tượng luôn có `this` tham chiếu đến đối tượng đó. -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 object is "before the dot". +Trong JavaScript `this` "tự do", giá trị của nó được đánh giá tại thời điểm gọi và không phụ thuộc vào vị trí khai báo phương thức, mà phụ thuộc vào đối tượng nào "trước dấu chấm". -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, the greater flexibility creates more possibilities for mistakes. +Khái niệm về thời gian chạy được đánh giá `this` có cả ưu điểm và nhược điểm. Một mặt, một hàm có thể được sử dụng lại cho các đối tượng khác nhau. Mặt khác, tính linh hoạt cao hơn tạo ra nhiều khả năng mắc sai lầm hơn. -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 avoid problems. +Ở đây, vị trí của chúng ta không phải là đánh giá liệu quyết định thiết kế ngôn ngữ này là tốt hay xấu. Chúng ta sẽ hiểu làm thế nào để làm việc với nó, làm thế nào để nhận được lợi ích và tránh các vấn đề. ``` -## Arrow functions have no "this" +## Các arrow function không có "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. +Các arrow function rất đặc biệt: chúng không có `this` "của riêng chúng". Nếu chúng ta tham chiếu `this` từ một hàm như vậy, thì nó được lấy từ hàm "bình thường" bên ngoài. -For instance, here `arrow()` uses `this` from the outer `user.sayHi()` method: +Chẳng hạn, ở đây `arrow()` sử dụng `this` từ phương thức `user.sayHi()` bên ngoài: ```js run let user = { @@ -253,18 +253,18 @@ 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. +Đó là một tính năng đặc biệt của arrow function, nó rất hữu ích khi chúng ta thực sự không muốn có một `this` riêng biệt, mà muốn lấy nó từ ngữ cảnh bên ngoài. Ở phần sau của chương chúng ta sẽ đi sâu hơn vào các arrow function. -## Summary +## Tóm tắt -- 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`. +- Các hàm được lưu trữ trong các thuộc tính đối tượng được gọi là "phương thức". +- Các phương thức cho phép các đối tượng "hành động" như `object.doSomething()`. +- Các phương thức có thể tham chiếu đối tượng như `this`. -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. -- A 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`. +Giá trị của `this` được xác định trong thời gian chạy. +- Khi một hàm được khai báo, nó có thể sử dụng `this`, nhưng `this` đó không có giá trị cho đến khi hàm được gọi. +- Một hàm có thể được sao chép giữa các đối tượng. +- Khi một hàm được gọi theo cú pháp "phương thức": `object.method()`, giá trị của `this` trong khi gọi là `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. +Hãy lưu ý rằng các arrow function là đặc biệt: chúng không có `this`. Khi `this` được truy cập bên trong một arrow function, nó được lấy từ bên ngoài.