You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/02-function-prototype/1-changing-prototype/solution.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,18 +3,18 @@ Answers:
3
3
4
4
1.`true`.
5
5
6
-
The assignment to `Rabbit.prototype`sets up `[[Prototype]]`for new objects, but it does not affect the existing ones.
6
+
Thay đổi `Rabbit.prototype`chỉ ảnh hưởng tới `[[Prototype]]`của đối tượng được tạo ra sau này, không ảnh hưởng đến các đối tượng đã tạo từ trước.
7
7
8
8
2.`false`.
9
9
10
-
Objects are assigned by reference. The object from`Rabbit.prototype`is not duplicated, it's still a single object is referenced both by `Rabbit.prototype`and by the `[[Prototype]]`of`rabbit`.
10
+
Đối tượng được gán theo tham chiếu. Đối tượng từ`Rabbit.prototype`không được nhân bản khi gán cho `[[Prototype]]` cho nên `Rabbit.prototype`và `[[Prototype]]`của`rabbit` là hai tham chiếu tới một đối tượng.
11
11
12
-
So when we change its content through one reference, it is visible through the other one.
12
+
Nên khi ta thay đổi đối tượng qua một tham chiếu, sự thay đổi này cũng thấy được từ tham chiếu kia.
13
13
14
14
3.`true`.
15
15
16
-
All `delete`operations are applied directly to the object. Here `delete rabbit.eats`tries to remove `eats`property from `rabbit`, but it doesn't have it. So the operation won't have any effect.
16
+
Hành động xóa bằng toán tử `delete`không tác động tới nguyên mẫu. Ở đây `delete rabbit.eats`chỉ cố xóa thuộc tính `eats`của `rabbit`, nhưng nó không tồn tại. Nên hành động này không gây ảnh hưởng gì.
17
17
18
18
4.`undefined`.
19
19
20
-
The property`eats`is deleted from the prototype, it doesn't exist any more.
20
+
Thuộc tính`eats`bị xóa khỏi nguyên mẫu, vậy nên nó không thể tìm thấy nữa.
We can use such approach if we are sure that `"constructor"`property has the correct value.
1
+
Chúng ta chỉ có thể làm vậy nếu chắn chắn rằng thuộc tính `"constructor"`chứa giá trị đúng.
2
2
3
-
For instance, if we don't touch the default `"prototype"`, then this code works for sure:
3
+
Ví dụ, nếu thuộc tính `"prototype"` mặc định không bị thay đổi, thì đoạn mã chắc chắn làm việc được:
4
4
5
5
```js run
6
6
functionUser(name) {
7
7
this.name= name;
8
8
}
9
9
10
-
let user =newUser('John');
11
-
let user2 =newuser.constructor('Pete');
10
+
let user =newUser('Việt');
11
+
let user2 =newuser.constructor('Nam');
12
12
13
-
alert( user2.name ); //Pete (worked!)
13
+
alert( user2.name ); //Nam (làm việc!)
14
14
```
15
15
16
-
It worked, because`User.prototype.constructor == User`.
16
+
Nó làm việc đúng bởi vì`User.prototype.constructor == User`.
17
17
18
-
..But if someone, so to say, overwrites`User.prototype`and forgets to recreate`"constructor"`, then it would fail.
18
+
...Nhưng nếu ai đó ghi đè mất`User.prototype`và quên tạo lại`"constructor"`, đoạn mã sẽ không làm việc đúng nữa:
19
19
20
-
For instance:
20
+
Ví dụ:
21
21
22
22
```js run
23
23
functionUser(name) {
@@ -27,18 +27,18 @@ function User(name) {
27
27
User.prototype= {}; // (*)
28
28
*/!*
29
29
30
-
let user =newUser('John');
31
-
let user2 =newuser.constructor('Pete');
30
+
let user =newUser('Việt');
31
+
let user2 =newuser.constructor('Nam');
32
32
33
33
alert( user2.name ); // undefined
34
34
```
35
35
36
-
Why `user2.name`is`undefined`?
36
+
Tại sao `user2.name`là`undefined`?
37
37
38
-
Here's how `new user.constructor('Pete')`works:
38
+
Đây là cách `new user.constructor('Nam')`làm việc:
39
39
40
-
1.First, it looks for`constructor`in`user`. Nothing.
41
-
2.Then it follows the prototype chain. The prototype of`user`is`User.prototype`, and it also has nothing.
42
-
3.The value of`User.prototype`is a plain object`{}`, its prototype is `Object.prototype`. And there is `Object.prototype.constructor == Object`. So it is used.
40
+
1.Trước tiên nó tìm`constructor`trong`user`. Không có.
41
+
2.Sau đó nó theo chuỗi nguyên mẫu. Nguyên mẫu của`user`là`User.prototype`, và cũng không có.
42
+
3.Giá trị của`User.prototype`là đối tượng trống`{}`, nên mặc định nó thừa kế từ `Object.prototype`. Và có `Object.prototype.constructor == Object`. Nên `Object` được sử dụng.
43
43
44
-
At the end, we have`let user2 = new Object('Pete')`. The built-in `Object`constructor ignores arguments, it always creates an empty object -- that's what we have in `user2`after all.
44
+
Cuối cùng chúng ta có`let user2 = new Object('Nam')`. `Object`là một hàm tạo có sẵn, nó bỏ qua mọi đối số truyền vào và tạo ra một đối tượng trống -- vậy `user2`là đối tượng trống không có thuộc tính nào.
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/task.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,14 +2,14 @@ importance: 5
2
2
3
3
---
4
4
5
-
# Create an object with the same constructor
5
+
# Tạo đối tượng có cùng constructor
6
6
7
-
Imagine, we have an arbitrary object `obj`, created by a constructor function -- we don't know which one, but we'd like to create a new object using it.
7
+
Tưởng tượng, ta có đối tượng bất kỳ `obj`, tạo ra từ một hàm tạo -- chúng ta không biết về hàm này, nhưng lại muốn tạo đối tượng khác bằng nó.
8
8
9
-
Can we do it like that?
9
+
Có thể làm như thế này không?
10
10
11
11
```js
12
12
let obj2 =newobj.constructor();
13
13
```
14
14
15
-
Give an example of a constructor function for `obj` which lets such code work right. And an example that makes it work wrong.
15
+
Cho biết khi nào đoạn mã trên làm việc và không làm việc, cho ví dụ minh họa từng trường hợp?
Remember, new objects can be created with a constructor function, like`new F()`.
3
+
Nhớ rằng, các đối tượng có thể tạo bằng hàm tạo (constructor), chẳng hạn như`new F()`.
4
4
5
-
If`F.prototype`is an object, then `new`operator uses it to set`[[Prototype]]`for the new object.
5
+
Nếu`F.prototype`là một đối tượng, thì toán tử `new`dùng nó để đặt cho`[[Prototype]]`của đối tượng mới được tạo ra.
6
6
7
7
```smart
8
-
JavaScript had prototypal inheritance from the beginning. It was one of the core features of the language.
8
+
Từ thuở ban đầu JavaScript đã có thừa kế nguyên mẫu. Đây là một trong những tính năng cốt lõi của ngôn ngữ này.
9
9
10
-
But in the old times, there was no direct access to it. The only thing that worked reliably was a `"prototype"` property of the constructor function, described in this chapter. So there are many scripts that still use it.
10
+
Nhưng ngày xưa, không có cách nào để truy cập trực tiếp đến nó. Cách duy nhất có thể dùng để làm việc với thừa kế là sử dụng thuộc tính `"prototype"` của hàm tạo. Vậy nên ngày nay còn nhiều script vẫn sử dụng nó.
11
11
```
12
12
13
-
Please note that`F.prototype`here means a regular property named `"prototype"`on`F`. It sounds something similar to the term "prototype", but here we really mean a regular property with this name.
13
+
Chú ý rằng`F.prototype`chỉ là một thuộc tính thông thường có tên `"prototype"`của`F`. Dù tên nó giống thuật ngữ "prototype", nhưng nó không phải là một thuộc tính đặc biệt.
14
14
15
-
Here's the example:
15
+
Đây là ví dụ:
16
16
17
17
```js run
18
18
let animal = {
@@ -32,90 +32,90 @@ let rabbit = new Rabbit("White Rabbit"); // rabbit.__proto__ == animal
32
32
alert( rabbit.eats ); // true
33
33
```
34
34
35
-
Setting `Rabbit.prototype = animal`literally states the following: "When a `new Rabbit` is created, assign its `[[Prototype]]`to`animal`".
35
+
Cài đặt `Rabbit.prototype = animal`có nghĩa là: "Khi một đối tượng tạo bằng`new Rabbit`, đặt thuộc tính `[[Prototype]]`của nó thành`animal`".
36
36
37
-
That's the resulting picture:
37
+
Đây là hình ảnh của kết quả:
38
38
39
39

40
40
41
-
On the picture, `"prototype"`is a horizontal arrow, meaning a regular property, and`[[Prototype]]`is vertical, meaning the inheritance of `rabbit`from`animal`.
41
+
Ở hình trên, `"prototype"`là một mũi tên nằm ngang, mang nghĩa là một thuộc tính thông thường, và`[[Prototype]]`là mũi tên thẳng đứng, mang nghĩa `rabbit`thừa kế từ`animal`.
42
42
43
-
```smart header="`F.prototype`only used at `new F` time"
44
-
`F.prototype`property is only used when `new F` is called, it assigns `[[Prototype]]`of the new object. After that, there's no connection between `F.prototype`and the new object. Think of it as a "one-time gift".
43
+
```smart header="`F.prototype`chỉ được dùng khi gọi `new F()`"
44
+
Thuộc tính `F.prototype`được gán cho `[[Prototype]]`một lần duy nhất khi gọi `new F()`. Sau đó không còn liên hệ giữa `F.prototype`và đối tượng mới này.
45
45
46
-
If, after the creation, `F.prototype`property changes (`F.prototype = <another object>`), then new objects created by `new F` will have another object as `[[Prototype]]`, but already existing objects keep the old one.
46
+
Chẳng hạn, sau khi tạo đối tượng, `F.prototype`bị thay đổi (`F.prototype = <một đối tượng khác>`), thì `[[Prototype]]` của đối tượng không bị thay đổi theo. Sự thay đổi của `F.prototype` chỉ ảnh hưởng tới các đối tượng được tạo ra sau này bằng `new F()`.
47
47
```
48
48
49
-
## Default F.prototype, constructor property
49
+
## F.prototype mặc định, thuộc tính "constructor"
50
50
51
-
Every function has the `"prototype"` property even if we don't supply it.
51
+
Mọi hàm đều có sẵn thuộc tính `"prototype"` ngay cả khi ta không tạo.
52
52
53
-
The default `"prototype"` is an object with the only property `constructor` that points back to the function itself.
53
+
Giá trị mặc định của `"prototype"` là một đối tượng chỉ có một thuộc tính duy nhất `constructor` trỏ ngược lại tới hàm.
alert(rabbit.constructor== Rabbit); // true (lấy từ nguyên mẫu)
87
87
```
88
88
89
89

90
90
91
-
We can use `constructor`property to create a new object using the same constructor as the existing one.
91
+
Chúng ta có thể sử dụng thuộc tính `constructor`để tạo đối tượng mới từ constructor của một đối tượng đã có:
92
92
93
-
Like here:
93
+
Chẳng hạn:
94
94
95
95
```js run
96
96
functionRabbit(name) {
97
97
this.name= name;
98
98
alert(name);
99
99
}
100
100
101
-
let rabbit =newRabbit("White Rabbit");
101
+
let rabbit =newRabbit("Thỏ trắng");
102
102
103
103
*!*
104
-
let rabbit2 =newrabbit.constructor("Black Rabbit");
104
+
let rabbit2 =newrabbit.constructor("Thỏ đen");
105
105
*/!*
106
106
```
107
107
108
-
That's handy when we have an object, don't know which constructor was used for it (e.g. it comes from a 3rd party library), and we need to create another one of the same kind.
108
+
Cách này rất tiện nếu chúng ta có một đối tượng, không biết constructor nào đã tạo ra nó (ví dụ đối tượng từ một thư viện ngoài), và muốn tạo một đối tượng khác cùng loại.
109
109
110
-
But probably the most important thing about `"constructor"` is that...
110
+
Nhưng nên cẩn thận vì...
111
111
112
-
**...JavaScript itself does not ensure the right`"constructor"`value.**
112
+
**...JavaScript không thể đảm bảo giá trị`"constructor"`luôn đúng.**
113
113
114
-
Yes, it exists in the default `"prototype"`for functions, but that's all. What happens with it later -- is totally on us.
114
+
Vâng, thuộc tính `constructor` tồn tại trong `"prototype"`mặc định của mọi hàm, nhưng đó là tất cả những gì JavaScript làm. Chuyện gì xảy ra sau đó hoàn toàn do chúng ta quyết định.
115
115
116
-
In particular, if we replace the default prototype as a whole, then there will be no `"constructor"` in it.
116
+
Cụ thể, nếu ta thay thế `prototype` mặc định bằng một đối tượng khác không có `constructor`, đối tượng tạo ra không còn biết constructor tạo ra nó nữa.
So, to keep the right `"constructor"` we can choose to add/remove properties to the default `"prototype"` instead of overwriting it as a whole:
132
+
Cho nên, để giữ lại `"constructor"`, chúng ta phải thêm/xóa các thuộc tính khỏi `prototype` mặc định thay vì ghi đè toàn bộ.
133
133
134
134
```js
135
135
functionRabbit() {}
136
136
137
-
//Not overwrite Rabbit.prototype totally
138
-
//just add to it
137
+
//Không ghi đè toàn bộ Rabbit.prototype
138
+
//chỉ bổ sung vào đó
139
139
Rabbit.prototype.jumps=true
140
-
//the default Rabbit.prototype.constructor is preserved
140
+
// Rabbit.prototype.constructor vẫn được giữ
141
141
```
142
142
143
-
Or, alternatively, recreate the `constructor` property manually:
143
+
Hoặc tạo lại thuộc tính `constructor`:
144
144
145
145
```js
146
146
Rabbit.prototype= {
@@ -150,26 +150,26 @@ Rabbit.prototype = {
150
150
*/!*
151
151
};
152
152
153
-
//now constructor is also correct, because we added it
153
+
//giờ constructor vẫn đúng, vì chúng ta đã thêm nó
154
154
```
155
155
156
156
157
-
## Summary
157
+
## Tóm tắt
158
158
159
-
In this chapter we briefly described the way of setting a `[[Prototype]]` for objects created via a constructor function. Later we'll see more advanced programming patterns that rely on it.
159
+
Trong bài này chúng ta đã mô tả ngắn gọn cách cài đặt `[[Prototype]]` cho các đối tượng tạo ra bằng hàm tạo. Sau này bạn sẽ thấy nhiều mô hình lập trình dựa vào nó.
160
160
161
-
Everything is quite simple, just few notes to make things clear:
161
+
Mọi thứ khá đơn giản, chỉ có vài lưu ý sau:
162
162
163
-
- The `F.prototype` property is not the same as `[[Prototype]]`. The only thing `F.prototype` does: it sets `[[Prototype]]` of new objects when `new F()` is called.
164
-
- The value of `F.prototype` should be either an object or null: other values won't work.
165
-
- The `"prototype"` property only has such a special effect when set on a constructor function, and invoked with `new`.
163
+
- Thuộc tính `F.prototype` không phải là `[[Prototype]]`. Giá trị của `F.prototype` được gán cho `[[Prototype]]` khi gọi `new F()`, sau đó chúng hoàn toàn độc lập nhau.
164
+
- Giá trị của `F.prototype` có thể là đối tượng hoặc null: mọi giá trị kiểu cơ sở đều không hoạt động.
165
+
- Thuộc tính `"prototype"` chỉ có tác dụng khi cài đặt nó cho một hàm tạo và gọi hàm này bằng `new`.
166
166
167
-
On regular objects the `prototype` is nothing special:
167
+
Nếu cài đặt `prototype` cho một đối tượng thông thường, nó không còn gì đặc biệt:
168
168
```js
169
169
let user = {
170
170
name:"John",
171
-
prototype:"Bla-bla"//no magic at all
171
+
prototype:"Bla-bla"//không có gì đặc biệt
172
172
};
173
173
```
174
174
175
-
By default all functions have `F.prototype= { constructor: F }`, so we can get the constructor of an object by accessing its `"constructor"` property.
175
+
Mặc định tất cả các hàm có `F.prototype= { constructor: F }`, giúp ta có thể lấy được hàm tạo của một đối tượng bằng cách truy cập thuộc tính `constructor` của nó.
0 commit comments