Skip to content

Commit c3e32bb

Browse files
author
Phùng Hùng
committed
Translate Native prototypes into Vietnamese
1 parent 7e8b02d commit c3e32bb

File tree

5 files changed

+80
-80
lines changed

5 files changed

+80
-80
lines changed

1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/solution.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Function.prototype.defer = function(ms) {
66
};
77

88
function f() {
9-
alert("Hello!");
9+
alert("Xin chào!");
1010
}
1111

12-
f.defer(1000); // shows "Hello!" after 1 sec
12+
f.defer(1000); // hiện "Xin chào!" sau 1 giây
1313
```

1-js/08-prototypes/03-native-prototypes/1-defer-to-prototype/task.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ importance: 5
22

33
---
44

5-
# Add method "f.defer(ms)" to functions
5+
# Thêm phương thức "f.defer(ms)" tới các hàm
66

7-
Add to the prototype of all functions the method `defer(ms)`, that runs the function after `ms` milliseconds.
7+
Thêm vào nguyên mẫu của các hàm phương thức `defer(ms)`, chạy hàm sau `ms` mi-li-giây.
88

9-
After you do it, such code should work:
9+
Đảm bảo đoạn mã sau làm việc:
1010

1111
```js
1212
function f() {
13-
alert("Hello!");
13+
alert("Xin chào!");
1414
}
1515

16-
f.defer(1000); // shows "Hello!" after 1 second
16+
f.defer(1000); // hiện "Xin chào!" sau 1 giây
1717
```

1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/solution.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ Function.prototype.defer = function(ms) {
88
}
99
};
1010

11-
// check it
11+
// kiểm tra
1212
function f(a, b) {
1313
alert( a + b );
1414
}
1515

16-
f.defer(1000)(1, 2); // shows 3 after 1 sec
16+
f.defer(1000)(1, 2); // hiện 3 sau 1 giây
1717
```

1-js/08-prototypes/03-native-prototypes/2-defer-to-prototype-extended/task.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ importance: 4
22

33
---
44

5-
# Add the decorating "defer()" to functions
5+
# Thêm hàm trang trí "defer()" cho mọi hàm
66

7-
Add to the prototype of all functions the method `defer(ms)`, that returns a wrapper, delaying the call by `ms` milliseconds.
7+
Thêm vào nguyên mẫu của các hàm phương thức `defer(ms)`, trả về một hàm bao, làm chậm lời gọi hàm đi `ms` mi-li-giây.
88

9-
Here's an example of how it should work:
9+
Đây là ví dụ về cách làm việc của nó:
1010

1111
```js
1212
function f(a, b) {
1313
alert( a + b );
1414
}
1515

16-
f.defer(1000)(1, 2); // shows 3 after 1 second
16+
f.defer(1000)(1, 2); // hiện 3 sau 1 giây
1717
```
1818

19-
Please note that the arguments should be passed to the original function.
19+
Chú ý rằng các đối số được truyền tới hàm gốc.
Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
# Native prototypes
1+
# Các nguyên mẫu có sẵn
22

3-
The `"prototype"` property is widely used by the core of JavaScript itself. All built-in constructor functions use it.
3+
Thuộc tính `"prototype"` được dùng rất nhiều bởi chính JavaScript. Tất cả các constructor có sẵn đều sử dụng nó.
44

5-
We'll see how it is for plain objects first, and then for more complex ones.
5+
Trước tiên ta tìm hiểu về hàm tạo ra các đối tượng thuần, sau đó là các đối tượng có sẵn phức tạp hơn.
66

77
## Object.prototype
88

9-
Let's say we output an empty object:
9+
Giả sử chúng ta có một đối tượng trống:
1010

1111
```js run
1212
let obj = {};
1313
alert( obj ); // "[object Object]" ?
1414
```
1515

16-
Where's the code that generates the string `"[object Object]"`? That's a built-in `toString` method, but where is it? The `obj` is empty!
16+
Giá trị xuất ra là chuỗi `"[object Object]"` là do phương thức `toString`, còn thực tế `obj` là rỗng và không hề có `toString`. Vậy `toString` lấy ở đâu?
1717

18-
...But the short notation `obj = {}` is the same as `obj = new Object()`, where `Object` is a built-in object constructor function, with its own `prototype` referencing a huge object with `toString` and other methods.
18+
...Thực ra cách viết `obj = {}` hoàn toàn giống `obj = new Object()`, ở đó `Object` constructor có sẵn, có thuộc tính `prototype` tham chiếu tới một đối tượng khổng lồ chứa rất nhiều phương thức trong đó có `toString`.
1919

20-
Here's what's going on:
20+
Đây là hình ảnh mô tả chuyện gì đã xảy ra:
2121

2222
![](object-prototype.png)
2323

24-
When `new Object()` is called (or a literal object `{...}` is created), the `[[Prototype]]` of it is set to `Object.prototype` according to the rule that we discussed in the previous chapter:
24+
Khi tạo đối tượng bằng `new Object()` (hoặc bằng `{...}`), `Object.prototype` được gán cho `[[Prototype]]` của đối tượng, đây là quy tắc ta đã học ở bài trước:
2525

2626
![](object-prototype-1.png)
2727

28-
So then when `obj.toString()` is called the method is taken from `Object.prototype`.
28+
Cho nên khi gọi `obj.toString()` thì phương thức này được lấy từ `Object.prototype`.
2929

30-
We can check it like this:
30+
Ta có thể kiểm tra điều này:
3131

3232
```js run
3333
let obj = {};
@@ -36,80 +36,80 @@ alert(obj.__proto__ === Object.prototype); // true
3636
// obj.toString === obj.__proto__.toString == Object.prototype.toString
3737
```
3838

39-
Please note that there is no additional `[[Prototype]]` in the chain above `Object.prototype`:
39+
Chú ý rằng `Object.prototype` không có nguyên mẫu, thuộc tính `[[Prototype]]` của nó là `null`:
4040

4141
```js run
4242
alert(Object.prototype.__proto__); // null
4343
```
4444

45-
## Other built-in prototypes
45+
## Các nguyên mẫu có sẵn khác
4646

47-
Other built-in objects such as `Array`, `Date`, `Function` and others also keep methods in prototypes.
47+
Các constructor khác như `Array`, `Date`, `Function` ... cũng có thuộc tính `prototype` nơi giữ các phương thức có sẵn.
4848

49-
For instance, when we create an array `[1, 2, 3]`, the default `new Array()` constructor is used internally. So the array data is written into the new object, and `Array.prototype` becomes its prototype and provides methods. That's very memory-efficient.
49+
Ví dụ, khi tạo tạo mảng `[1, 2, 3]`, JavaScript tự động gọi `new Array()`. Mảng là đối tượng được tạo ra từ `Array`, và do vậy `Array.prototype` trở thành nguyên mẫu của mảng và cung cấp cho mảng nhiều phương thức có sẵn.
5050

51-
By specification, all of the built-in prototypes have `Object.prototype` on the top. Sometimes people say that "everything inherits from objects".
51+
Tuy nhiên khác với `Object.prototype` các nguyên mẫu này vẫn có nguyên mẫu. Nguyên mẫu của chúng chính là `Object.prototype`. Do vậy người ta còn nói "mọi thứ đều thừa kế từ `Object.prototype`".
5252

53-
Here's the overall picture (for 3 built-ins to fit):
53+
Đây là hình ảnh minh họa với 3 nguyên mẫu:
5454

5555
![](native-prototypes-classes.png)
5656

57-
Let's check the prototypes manually:
57+
Cùng kiểm tra lại:
5858

5959
```js run
6060
let arr = [1, 2, 3];
6161

62-
// it inherits from Array.prototype?
62+
// arr thừa kế từ Array.prototype?
6363
alert( arr.__proto__ === Array.prototype ); // true
6464

65-
// then from Object.prototype?
65+
// Array.prototype thừa kế từ Object.prototype?
6666
alert( arr.__proto__.__proto__ === Object.prototype ); // true
6767

68-
// and null on the top.
68+
// Object.prototype không thừa kế từ ai cả
6969
alert( arr.__proto__.__proto__.__proto__ ); // null
7070
```
7171

72-
Some methods in prototypes may overlap, for instance, `Array.prototype` has its own `toString` that lists comma-delimited elements:
72+
Các phương thức trong các nguyên mẫu có thể "đè" lên nhau, ví dụ, `Array.prototype` có phương thức `toString` giúp liệt kê các phần tử của mảng với dấu phảy ngăn cách:
7373

7474
```js run
7575
let arr = [1, 2, 3]
76-
alert(arr); // 1,2,3 <-- the result of Array.prototype.toString
76+
alert(arr); // 1,2,3 <-- là kết quả của Array.prototype.toString
7777
```
7878

79-
As we've seen before, `Object.prototype` has `toString` as well, but `Array.prototype` is closer in the chain, so the array variant is used.
79+
Nhưng `Object.prototype` cũng có `toString`. Vậy `arr` lấy `toString` từ `Array.prototype` hay từ `Object.prototype`? Câu trả lời rất đơn giản: nó lấy từ nguyên mẫu gần nó nhất tức `Array.prototype`.
8080

8181

8282
![](native-prototypes-array-tostring.png)
8383

8484

85-
In-browser tools like Chrome developer console also show inheritance (`console.dir` may need to be used for built-in objects):
85+
Trong Developer console của trình duyệt bạn cũng có thể thấy được chuỗi thừa kế bằng lệnh `console.dir`:
8686

8787
![](console_dir_array.png)
8888

89-
Other built-in objects also work the same way. Even functions -- they are objects of a built-in `Function` constructor, and their methods (`call`/`apply` and others) are taken from `Function.prototype`. Functions have their own `toString` too.
89+
Các đối tượng có sẵn khác cũng làm việc tương tự. Ngay cả các hàm -- là đối tượng tạo ra bởi constructor `Function`, thực ra lấy các phương thức của nó(`call`/`apply` và phương thức khác) từ `Function.prototype`. Các hàm cũng có được phương thức `toString` từ đây.
9090

9191
```js run
9292
function f() {}
9393

9494
alert(f.__proto__ == Function.prototype); // true
95-
alert(f.__proto__.__proto__ == Object.prototype); // true, inherit from objects
95+
alert(f.__proto__.__proto__ == Object.prototype); // true
9696
```
9797

98-
## Primitives
98+
## Các giá trị kiểu cơ sở
9999

100-
The most intricate thing happens with strings, numbers and booleans.
100+
Đối với các giá trị kiểu cơ sở như chuỗi, số và giá trị lôgic câu chuyện có phức tạp hơn đôi chút.
101101

102-
As we remember, they are not objects. But if we try to access their properties, then temporary wrapper objects are created using built-in constructors `String`, `Number`, `Boolean`, they provide the methods and disappear.
102+
Như ta đã biết, chúng không phải là các đối tượng. Nhưng nếu ta cố tình truy cập các thuộc tính hay phương thức của chúng, một đối tượng bao được tạo bằng các constructor `String`, `Number`, `Boolean` sẽ thay thế và cung cấp các thuộc tính và phương thức này. Sau khi sử dụng xong đối tượng bảo bị xóa.
103103

104-
These objects are created invisibly to us and most engines optimize them out, but the specification describes it exactly this way. Methods of these objects also reside in prototypes, available as `String.prototype`, `Number.prototype` and `Boolean.prototype`.
104+
Các thuộc tính và phương thức của đối tượng thực ra cũng được lấy từ các nguyên mẫu sẵn có đó là `String.prototype`, `Number.prototype` `Boolean.prototype`.
105105

106-
```warn header="Values `null` and `undefined` have no object wrappers"
107-
Special values `null` and `undefined` stand apart. They have no object wrappers, so methods and properties are not available for them. And there are no corresponding prototypes too.
106+
```warn header="Các giá trị `null` and `undefined` không có đối tượng bao"
107+
Các giá trị `null` `undefined` khác với tất cả các giá trị cơ sở khác. Chúng không có đối tượng bao, nên cũng không có các thuộc tính và phương thức. Và do đó cũng không có nguyên mẫu.
108108
```
109109
110-
## Changing native prototypes [#native-prototype-change]
110+
## Thay đổi các nguyên mẫu có sẵn [#native-prototype-change]
111111
112-
Native prototypes can be modified. For instance, if we add a method to `String.prototype`, it becomes available to all strings:
112+
Các nguyên mẫu có sẵn có thể thay đổi được. Ví dụ, nếu bạn thêm vào `String.prototype` một phương thức, phương thức này có thể được dùng cho mọi chuỗi:
113113
114114
```js run
115115
String.prototype.show = function() {
@@ -119,32 +119,32 @@ String.prototype.show = function() {
119119
"BOOM!".show(); // BOOM!
120120
```
121121

122-
During the process of development, we may have ideas for new built-in methods we'd like to have, and we may be tempted to add them to native prototypes. But that is generally a bad idea.
122+
Trong quá trình phát triển, chúng ta có thể có những ý tưởng về các phương thức mới và muốn thêm nó vào các nguyên mẫu có sẵn. Nhưng đây không phải là cách làm tốt.
123123

124124
```warn
125-
Prototypes are global, so it's easy to get a conflict. If two libraries add a method `String.prototype.show`, then one of them will be overwriting the other.
125+
Các nguyên mẫu được dùng ở mọi nơi, nên rất dễ xảy ra xung đột. Nếu hai thư viện cùng thêm phương thức `String.prototype.show`, một trong số chúng sẽ ghi đè lên thư viện kia.
126126
127-
So, generally, modifying a native prototype is considered a bad idea.
127+
Vì thế, nói chung sửa đổi nguyên mẫu có sẵn là một ý tưởng tồi.
128128
```
129129

130-
**In modern programming, there is only one case where modifying native prototypes is approved. That's polyfilling.**
130+
**Trong lập trình hiện đại, chỉ có một trường hợp duy nhất có thể thay đổi nguyên mẫu có sẵn.Đó là polyfilling.**
131131

132-
Polyfilling is a term for making a substitute for a method that exists in JavaScript specification, but not yet supported by current JavaScript engine.
132+
Polyfilling là tạo một phương thức thay thế cho một phương thức đã có trong đặc tả nhưng chưa được hỗ trợ bởi JavaScript engine hiện tại.
133133

134-
Then we may implement it manually and populate the built-in prototype with it.
134+
Lúc này ta phải tự viết phương thức sao cho nó hoạt động giống như phương thức trong đặc tả, sau đó thêm nó vào nguyên mẫu như trong đặc tả.
135135

136-
For instance:
136+
Ví dụ:
137137

138138
```js run
139-
if (!String.prototype.repeat) { // if there's no such method
140-
// add it to the prototype
139+
if (!String.prototype.repeat) { // nếu không có phương thức
140+
// thêm nó vào nguyên mẫu này
141141

142142
String.prototype.repeat = function(n) {
143-
// repeat the string n times
143+
// lặp lại chuỗi n lần
144144

145-
// actually, the code should be a little bit more complex than that
146-
// (the full algorithm is in the specification)
147-
// but even an imperfect polyfill is often considered good enough
145+
// thực tế mã phức tạp hơn một chút
146+
// (toàn bộ thuật toán có trong đặc tả)
147+
// nhưng một phiên bản polyfill chưa hoàn hảo cũng đủ dùng rồi
148148
return new Array(n + 1).join(this);
149149
};
150150
}
@@ -153,44 +153,44 @@ alert( "La".repeat(3) ); // LaLaLa
153153
```
154154

155155

156-
## Borrowing from prototypes
156+
## Mượn phương thức từ các nguyên mẫu
157157

158-
In the chapter <info:call-apply-decorators#method-borrowing> we talked about method borrowing.
158+
Trong bài <info:call-apply-decorators#method-borrowing> chúng ta đã nói về mượn phương thức.
159159

160-
That's when we take a method from one object and copy it into another.
160+
Đó là khi chúng ta lấy phương thức của một đối tượng và dùng cho đối tượng khác.
161161

162-
Some methods of native prototypes are often borrowed.
162+
Một số phương thức của các nguyên mẫu có sẵn cũng có thể mượn được.
163163

164-
For instance, if we're making an array-like object, we may want to copy some array methods to it.
164+
Ví dụ, nếu chúng ta tạo một mảng giả, chúng ta muốn lấy vài phương thức của mảng thật cho nó.
165165

166-
E.g.
166+
Ví dụ:
167167

168168
```js run
169169
let obj = {
170-
0: "Hello",
171-
1: "world!",
170+
0: "Chào",
171+
1: "thế giới!",
172172
length: 2,
173173
};
174174

175175
*!*
176176
obj.join = Array.prototype.join;
177177
*/!*
178178

179-
alert( obj.join(',') ); // Hello,world!
179+
alert( obj.join(',') ); // Chào thế giới!
180180
```
181181

182-
It works, because the internal algorithm of the built-in `join` method only cares about the correct indexes and the `length` property, it doesn't check that the object is indeed the array. And many built-in methods are like that.
182+
Nó làm việc, bởi vì thuật toán bên trong của `join` hoàn toàn áp dụng được cho mảng giả. Còn nhiều phương thức có sẵn khác cũng có thể mượn được như vậy.
183183

184-
Another possibility is to inherit by setting `obj.__proto__` to `Array.prototype`, so all `Array` methods are automatically available in `obj`.
184+
Có một cách khác đó là cài đặt `obj.__proto__` thành `Array.prototype`, `obj` mượn được tất cả các phương thức của mảng.
185185

186-
But that's impossible if `obj` already inherits from another object. Remember, we only can inherit from one object at a time.
186+
Điều này không thể thực hiện nếu `obj` đã có một nguyên mẫu khác. Nhớ rằng, một đối tượng tại một thời điểm chỉ có một nguyên mẫu.
187187

188-
Borrowing methods is flexible, it allows to mix functionality from different objects if needed.
188+
Việc mượn phương thức rất mềm dẻo, nó cho phép phối hợp các tính năng từ nhiều đối tượng để áp dụng cho đối tượng hiện tại.
189189

190-
## Summary
190+
## Tóm tắt
191191

192-
- All built-in objects follow the same pattern:
193-
- The methods are stored in the prototype (`Array.prototype`, `Object.prototype`, `Date.prototype` etc).
194-
- The object itself stores only the data (array items, object properties, the date).
195-
- Primitives also store methods in prototypes of wrapper objects: `Number.prototype`, `String.prototype`, `Boolean.prototype`. Only `undefined` and `null` do not have wrapper objects.
196-
- Built-in prototypes can be modified or populated with new methods. But it's not recommended to change them. Probably the only allowable cause is when we add-in a new standard, but not yet supported by the engine JavaScript method.
192+
- Tất cả các đối tượng có sẵn đều tuân theo mô hình:
193+
- Các phương thức lưu trong nguyên mẫu (`Array.prototype`, `Object.prototype`, `Date.prototype`...).
194+
- Đối tượng chỉ chứa dữ liệu (phần tử mảng, thuộc tính, ngày/tháng...).
195+
- Các giá trị cơ sở giữ phương thức trong nguyên mẫu của đối tượng bao: `Number.prototype`, `String.prototype`, `Boolean.prototype`. Chỉ `undefined` `null` không có đối tượng bao.
196+
- Các nguyên mẫu có sẵn có thể thay đổi được hoặc bổ sung thêm phương thức mới. Nhưng không nên sửa chúng. Chỉ nên sửa nếu ta cần thêm các phương thức mới có trong đặc tả nhưng chưa được JavaScript engine hỗ trợ.

0 commit comments

Comments
 (0)