Skip to content

Commit 147e1ab

Browse files
author
Phùng Hùng
committed
Translate Property getters and setters into Vietnamese
1 parent 711d30e commit 147e1ab

File tree

1 file changed

+74
-74
lines changed
  • 1-js/07-object-properties/02-property-accessors

1 file changed

+74
-74
lines changed
Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,144 @@
11

2-
# Property getters and setters
2+
# Các thuộc tính getter và setter
33

4-
There are two kinds of properties.
4+
Có hai loại thuộc tính.
55

6-
The first kind is *data properties*. We already know how to work with them. All properties that we've been using till now were data properties.
6+
Đầu tiên là *thuộc tính dữ liệu* (data properties). Chúng ta đã biết và làm việc với chúng. Tất cả các thuộc tính chúng ta đã sử dụng cho đến giờ đều là các thuộc tính dữ liệu.
77

8-
The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code.
8+
Loại thứ hai sẽ được học trong bài này gọi là các *thuộc tính truy cập* (accessor properties). Về cơ bản chúng là các hàm có tác dụng lấy và cài đặt một giá trị - (tức là các phương thức), nhưng cách sử dụng giống một thuộc tính bình thường.
99

10-
## Getters and setters
10+
## Getter và Setter
1111

12-
Accessor properties are represented by "getter" and "setter" methods. In an object literal they are denoted by `get` and `set`:
12+
Các thuộc tính truy cập được biểu diễn bằng hai phương thức gọi là "getter" "setter". Trong literal đối tượng chúng được nhận biết bởi hai từ khóa `get` `set`:
1313

1414
```js
1515
let obj = {
1616
*!*get propName()*/!* {
17-
// getter, the code executed on getting obj.propName
17+
// getter, phương thức này chạy khi truy cập "obj.propName"
1818
},
1919

2020
*!*set propName(value)*/!* {
21-
// setter, the code executed on setting obj.propName = value
21+
// setter, phương thức này chạy khi gán "obj.propName = value"
2222
}
2323
};
2424
```
2525

26-
The getter works when `obj.propName` is read, the setter -- when it is assigned.
26+
Phương thức getter chạy khi truy cập `obj.propName`, setter chạy khi gán một giá trị cho nó.
2727

28-
For instance, we have a `user` object with `name` and `surname`:
28+
Ví dụ, ta có đối tượng `user` với thuộc tính `name` `surname`:
2929

3030
```js run
3131
let user = {
32-
name: "John",
33-
surname: "Smith"
32+
name: "Hùng",
33+
surname: "Phùng"
3434
};
3535
```
3636

37-
Now we want to add a "fullName" property, that should be "John Smith". Of course, we don't want to copy-paste existing information, so we can implement it as an accessor:
37+
Giờ ta muốn thêm thuộc tính `fullName` có giá trị là `"Phùng Hùng"`. Tất nhiên, chúng ta không sao chép thủ công các thông tin hiện có làm giá trị của `fullName`. Chúng ta có thể thực hiện việc này bằng một getter:
3838

3939
```js run
4040
let user = {
41-
name: "John",
42-
surname: "Smith",
41+
name: "Hùng",
42+
surname: "Phùng",
4343

4444
*!*
4545
get fullName() {
46-
return `${this.name} ${this.surname}`;
46+
return `${this.surname} ${this.name}`;
4747
}
4848
*/!*
4949
};
5050

5151
*!*
52-
alert(user.fullName); // John Smith
52+
alert(user.fullName); // Phùng Hùng
5353
*/!*
5454
```
5555

56-
From outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call* `user.fullName` as a function, we *read* it normally: the getter runs behind the scenes.
56+
Từ bên ngoài, các thuộc tính truy cập trông như thuộc tính dữ liệu. Nó cũng là ý tưởng cho sự xuất hiện của các thuộc tính truy cập. Chúng ta không gọi `user.fullName` như gọi phương thức, mà gọi giống như *đọc* một thuộc tính bình thường: getter sẽ tự động chạy "phía sau hậu trường".
5757

58-
As of now, `fullName` has only a getter. If we attempt to assign `user.fullName=`, there will be an error.
58+
Đến giờ, `fullName` mới chỉ có getter. Nếu chúng ta muốn thay đổi giá trị của nó bằng cách gán `user.fullName=` thì sẽ có lỗi:
5959

60-
Let's fix it by adding a setter for `user.fullName`:
60+
Để có thể gán giá trị cho một thuộc tính truy cập, cần tạo setter cho nó. Cùng thêm một setter cho `user.fullName`:
6161

6262
```js run
6363
let user = {
64-
name: "John",
65-
surname: "Smith",
64+
name: "Hùng",
65+
surname: "Phùng",
6666

6767
get fullName() {
68-
return `${this.name} ${this.surname}`;
68+
return `${this.surname} ${this.name}`;
6969
},
7070

7171
*!*
7272
set fullName(value) {
73-
[this.name, this.surname] = value.split(" ");
73+
[this.surname, this.name] = value.split(" ");
7474
}
7575
*/!*
7676
};
7777

78-
// set fullName is executed with the given value.
79-
user.fullName = "Alice Cooper";
78+
// Khi gán setter được chạy, đối số value lấy từ vế phải của =
79+
user.fullName = "Phùng Ngọc";
8080

81-
alert(user.name); // Alice
82-
alert(user.surname); // Cooper
81+
alert(user.name); // Ngọc
82+
alert(user.surname); // Phùng
8383
```
8484

85-
As the result, we have a "virtual" property `fullName`. It is readable and writable, but in fact does not exist.
85+
Kết quả là chúng ta có một thuộc tính "ảo" `fullName`. Ta có thể đọc và ghi nó, nhưng thực tế nó không tồn tại trong đối tượng.
8686

87-
```smart header="Accessor properties are only accessible with get/set"
88-
Once a property is defined with `get prop()` or `set prop()`, it's an accessor property, not a data property any more.
87+
```smart header="Các thuộc tính truy cập chỉ có thể truy cập nhờ getter và setter"
88+
Khi một thuộc tính đã được định nghĩa với `get prop()` hoặc `set prop()`, nó trở thành một thuộc tính truy cập, không phải là thuộc tính dữ liệu nữa.
8989
90-
- If there's a getter -- we can read `object.prop`, otherwise we can't.
91-
- If there's a setter -- we can set `object.prop=...`, otherwise we can't.
90+
- Chúng ta chỉ có thể đọc thuộc tính truy cập `object.prop` nếu có getter cho nó.
91+
- Chúng ta chỉ có thể ghi thuộc tính truy cập `object.prop=...` nếu có setter cho nó.
9292
93-
And in either case we can't `delete` an accessor property.
93+
Và trong cả hai trường hợp, ta không thể xóa một thuộc tính truy cập.
9494
```
9595

9696

97-
## Accessor descriptors
97+
## Descriptor của thuộc tính truy cập
9898

99-
Descriptors for accessor properties are different -- as compared with data properties.
99+
Các descriptor của thuộc trính truy cập khác với descriptor của thuộc tính dữ liệu mà ta đã học.
100100

101-
For accessor properties, there is no `value` and `writable`, but instead there are `get` and `set` functions.
101+
Nó không có `value` `writable`, mà thay bằng hai hàm `get` `set`.
102102

103-
So an accessor descriptor may have:
103+
Cụ thể descriptor của thuộc tính truy cập có:
104104

105-
- **`get`** -- a function without arguments, that works when a property is read,
106-
- **`set`** -- a function with one argument, that is called when the property is set,
107-
- **`enumerable`** -- same as for data properties,
108-
- **`configurable`** -- same as for data properties.
105+
- **`get`** -- hàm không có tham số, chạy khi đọc thuộc tính,
106+
- **`set`** -- hàm có một tham số, chạy khi ghi thuộc tính,
107+
- **`enumerable`** -- giống thuộc tính dữ liệu,
108+
- **`configurable`** -- giống thuộc tính dữ liệu.
109109

110-
For instance, to create an accessor `fullName` with `defineProperty`, we can pass a descriptor with `get` and `set`:
110+
Ví dụ, để tạo thuộc tính truy cập `fullName` bằng `defineProperty`, chúng ta có thể truyền một descriptor có hai phương thức `get` `set`:
111111

112112
```js run
113113
let user = {
114-
name: "John",
115-
surname: "Smith"
114+
name: "Hùng",
115+
surname: "Phùng"
116116
};
117117

118118
*!*
119119
Object.defineProperty(user, 'fullName', {
120120
get() {
121-
return `${this.name} ${this.surname}`;
121+
return `${this.surname} ${this.name}`;
122122
},
123123

124124
set(value) {
125-
[this.name, this.surname] = value.split(" ");
125+
[this.surname, this.name] = value.split(" ");
126126
}
127127
*/!*
128128
});
129129

130-
alert(user.fullName); // John Smith
130+
alert(user.fullName); // Phùng Hùng
131131

132132
for(let key in user) alert(key); // name, surname
133133
```
134134

135-
Please note once again that a property can be either an accessor or a data property, not both.
135+
Vui lòng chú ý một lần nữa, một thuộc tính chỉ có thể là thuộc tính truy cập hoặc thuộc tính dữ liệu, không thể là cả hai cùng lúc.
136136

137-
If we try to supply both `get` and `value` in the same descriptor, there will be an error:
137+
Nếu đưa cả `get` `value` trong một descriptor, sẽ gây ra lỗi:
138138

139139
```js run
140140
*!*
141-
// Error: Invalid property descriptor.
141+
// Lỗi: Thuộc tính descriptor không hợp lệ
142142
*/!*
143143
Object.defineProperty({}, 'prop', {
144144
get() {
@@ -149,11 +149,11 @@ Object.defineProperty({}, 'prop', {
149149
});
150150
```
151151

152-
## Smarter getters/setters
152+
## Getter/setter thông minh hơn
153153

154-
Getters/setters can be used as wrappers over "real" property values to gain more control over them.
154+
Getters/setters có thể dùng như một thuộc tính "bao" lấy thuộc tính thực thực, để kiểm soát giá trị được đưa vào.
155155

156-
For instance, if we want to forbid too short names for `user`, we can store `name` in a special property `_name`. And filter assignments in the setter:
156+
Ví dụ, nếu chúng ta muốn chặn một tên quá ngắn cho `user`, chúng ta có thể tạo một thuộc tính truy cập `name` lưu trong thuộc tính thực `_name` và thêm bước kiểm tra vào trong setter:
157157

158158
```js run
159159
let user = {
@@ -163,63 +163,63 @@ let user = {
163163

164164
set name(value) {
165165
if (value.length < 4) {
166-
alert("Name is too short, need at least 4 characters");
166+
alert("Tên quá ngắn, cần nhiều hơn 4 ký tự");
167167
return;
168168
}
169169
this._name = value;
170170
}
171171
};
172172

173-
user.name = "Pete";
174-
alert(user.name); // Pete
173+
user.name = "Hùng";
174+
alert(user.name); // Hùng
175175

176-
user.name = ""; // Name is too short...
176+
user.name = ""; // Tên quá ngắn, cần nhiều hơn 4 ký tự
177177
```
178178

179-
Technically, the external code may still access the name directly by using `user._name`. But there is a widely known agreement that properties starting with an underscore `"_"` are internal and should not be touched from outside the object.
179+
Vễ mặt kỹ thuật, mã bên ngoài vẫn có thể truy cập và thay đổi trực tiếp thuộc tính `user._name`. Nhưng có một thỏa thuận được chấp nhận rộng rãi rằng các thuộc tính có tên bắt đầu bằng `"_"` được coi là thuộc tính riêng của đối tượng và không nên truy cập hay thay đổi trực tiếp từ bên ngoài.
180180

181181

182-
## Using for compatibility
182+
## Cung cấp sự tương thích
183183

184-
One of the great ideas behind getters and setters -- they allow to take control over a "regular" data property at any moment by replacing it with getter and setter and tweak its behavior.
184+
Các getter và setter cho phép ta thay thế một thuộc tính dữ liệu thông thường bằng phiên bản khác sử dụng thuộc tính truy cập với khả năng kiểm soát tốt hơn.
185185

186-
Let's say we started implementing user objects using data properties `name` and `age`:
186+
Giả sử chúng ta tạo đối tượng người dùng có hai thuộc tính `name` `age`:
187187

188188
```js
189189
function User(name, age) {
190190
this.name = name;
191191
this.age = age;
192192
}
193193

194-
let john = new User("John", 25);
194+
let hung = new User("Hùng", 33);
195195

196-
alert( john.age ); // 25
196+
alert( hung.age ); // 33
197197
```
198198

199-
...But sooner or later, things may change. Instead of `age` we may decide to store `birthday`, because it's more precise and convenient:
199+
...Nhưng ngay sau đó, thay vì `age` ta quyết định sử dụng `birthday`, bởi nó chính xác và thuận tiện hơn:
200200

201201
```js
202202
function User(name, birthday) {
203203
this.name = name;
204204
this.birthday = birthday;
205205
}
206206

207-
let john = new User("John", new Date(1992, 6, 1));
207+
let hung = new User("Hùng", new Date(1986, 8, 3));
208208
```
209209

210-
Now what to do with the old code that still uses `age` property?
210+
Giờ ta phải làm gì với những mã cũ vẫn còn sử dụng thuộc tính `age`?
211211

212-
We can try to find all such places and fix them, but that takes time and can be hard to do if that code is written/used by many other people. And besides, `age` is a nice thing to have in `user`, right? In some places it's just what we want.
212+
Chúng ta có thể tìm và sửa lại, nhưng nó tốn rất nhiều thời gian và rất khó nếu mã được viết bởi những người khác. Hơn nữa sự có mặt của thuộc tính `age` trong đối tượng người dùng vẫn hợp lý và ta chỉ muốn thay đổi ở một số chỗ mà thôi.
213213

214-
Adding a getter for `age` solves the problem:
214+
Thêm thuộc tính truy cập cho `age` sẽ giải quyết được vấn đề này:
215215

216216
```js run no-beautify
217217
function User(name, birthday) {
218218
this.name = name;
219219
this.birthday = birthday;
220220

221221
*!*
222-
// age is calculated from the current date and birthday
222+
// age có thể tính được từ birthday
223223
Object.defineProperty(this, "age", {
224224
get() {
225225
let todayYear = new Date().getFullYear();
@@ -229,10 +229,10 @@ function User(name, birthday) {
229229
*/!*
230230
}
231231

232-
let john = new User("John", new Date(1992, 6, 1));
232+
let hung = new User("Hùng", new Date(1986, 8, 3));
233233

234-
alert( john.birthday ); // birthday is available
235-
alert( john.age ); // ...as well as the age
234+
alert( john.birthday ); // birthday vẫn truy cập được
235+
alert( john.age ); // ...và age cũng vậy
236236
```
237237

238-
Now the old code works too and we've got a nice additional property.
238+
Và giờ các đoạn mã cũ sử dụng `age` vẫn làm việc tốt.

0 commit comments

Comments
 (0)