Skip to content

Commit 7432200

Browse files
authored
Update translation of 1-js/09-classes/01-class (javascript-tutorial#637)
Update translation of 1-js/09-classes/01-class (javascript-tutorial#637)
1 parent 5d00bad commit 7432200

3 files changed

Lines changed: 77 additions & 104 deletions

File tree

1-js/09-classes/01-class/1-rewrite-to-class/task.md

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

55
# 重写为 class
66

7-
`Clock` 类是用函数式编写的,请以 class 语法重写它。
7+
`Clock` 类是以函数式编写的。请以 "class" 语法重写它。
88

9-
P.S. 请打开控制台以查看时钟显示
9+
P.S. 时钟在控制台(console)中滴答,打开控制台即可查看

1-js/09-classes/01-class/article.md

Lines changed: 74 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
# Class 基本语法
33

44
```quote author="Wikipedia"
5-
在面向对象的编程中,class 是用于创建对象的可扩展的程序代码模版,它为对象提供了状态(成员变量)的初始值和行为(成员函数和方法)的实现。
5+
在面向对象的编程中,*class* 是用于创建对象的可扩展的程序代码模版,它为对象提供了状态(成员变量)的初始值和行为(成员函数或方法)的实现。
66
```
77

8-
在日常开发中,我们经常要创建许多相同类型的对象,比如用户(users)、商品(goods)或者其他任何东西
8+
在日常开发中,我们经常需要创建许多相同类型的对象,例如用户(users)、商品(goods)或者任何其他东西
99

10-
<info:constructor-new> 章节中我们已经知道`new function` 可以做到这样
10+
正如我们在 <info:constructor-new> 一章中已经学到的`new function` 可以帮助我们实现这种需求
1111

12-
但是在现代 JavaScript 中,有一个更为高级的类(class)构造方式,它引入了对于面向对象编程很有用的功能
12+
但在现代 JavaScript 中,还有一个更高级的“类(class)构造方式,它引入许多非常棒的新功能,这些功能对于面向对象编程很有用
1313

14-
## class 语法
14+
## "class" 语法
1515

1616
基本语法是:
1717
```js
@@ -25,9 +25,9 @@ class MyClass {
2525
}
2626
```
2727

28-
然后通过 `new MyClass()` 来创建具有上述列出的所有方法的新对象。
28+
然后使用 `new MyClass()` 来创建具有上述列出的所有方法的新对象。
2929

30-
通过 `new` 关键词创建的对象会自动调用 `constructor()` 方法,因此我们可以在 `constructor()` 里初始化对象
30+
`new` 会自动调用 `constructor()` 方法,因此我们可以在 `constructor()` 中初始化对象
3131

3232
例如:
3333

@@ -44,29 +44,29 @@ class User {
4444

4545
}
4646

47-
// 使用方法
47+
// 用法
4848
let user = new User("John");
4949
user.sayHi();
5050
```
5151

5252
`new User("John")` 被调用:
5353
1. 一个新对象被创建。
54-
2. `constructor` 构造器使用给定的参数运行,并为其分配 `this.name`
54+
2. `constructor` 使用给定的参数运行,并为其分配 `this.name`
5555

56-
...然后我们就可以调用诸如 `user.sayHi` 这样的方法了
56+
……然后我们就可以调用对象方法了,例如 `user.sayHi`
5757

5858

59-
```warn header="类方法之间没有逗号"
60-
经验不足的开发者常犯的语法错误是在类方法之间加一个逗号
59+
```warn header="类的方法之间没有逗号"
60+
对于新手开发人员来说,常见的陷阱是在类的方法之间放置逗号,这会导致语法错误
6161
62-
这里的符号不要与对象字面量相混淆,在类中,不需要逗号。
62+
不要把这里的符号与对象字面量相混淆。在类中,不需要逗号。
6363
```
6464

6565
## 什么是 class?
6666

6767
所以,`class` 到底是什么?正如人们可能认为的那样,这不是一个全新的语言级实体。
6868

69-
让我们揭开其神秘面纱,看看类究竟是什么。这将会有助于你理解许多复杂的方面
69+
让我们揭开其神秘面纱,看看类究竟是什么。这将有助于我们理解许多复杂的方面
7070

7171
在 JavaScript 中,类是一种函数。
7272

@@ -84,68 +84,67 @@ alert(typeof User); // function
8484
*/!*
8585
```
8686

87-
`class User {...}` 构造器内部为我们做了什么:
88-
1. 创建一个以 `User` 为名称的函数,这是类声明的结果。
89-
- 函数代码来自于 `constructor` 中的方法(如果我们不写这样的方法,那么就假设它为空的)。
90-
2. 储存所有方法,例如 `User.prototype` 中的 `sayHi`
87+
`class User {...}` 构造实际上做了如下的事儿:
9188

92-
然后,对于新的对象,当我们调用方法时,它取自原型,就像我们在 <info:function-prototype> 章节中描述的那样。所以 `new User` 对象可以访问类中的方法。
89+
1. 创建一个名为 `User` 的函数,该函数成为类声明的结果。该函数的代码来自于 `constructor` 方法(如果我们不编写这种方法,那么它就被假定为空)。
90+
2. 存储类中的方法,例如 `User.prototype` 中的 `sayHi`
9391

94-
我们可以将 `class User` 声明结果解释为:
92+
`new User` 对象被创建后,当我们调用其方法时,它会从原型中获取对应的方法,正如我们在 <info:function-prototype> 一章中所讲的那样。因此,对象 `new User` 可以访问类中的方法。
9593

96-
![](class-user.svg)
94+
我们可以将 `class User` 声明的结果解释为:
9795

98-
下面这些代码很好的解释了它们:
96+
![](class-user.svg)
9997

98+
下面这些代码很好地解释了它们:
10099

101100
```js run
102101
class User {
103102
constructor(name) { this.name = name; }
104103
sayHi() { alert(this.name); }
105104
}
106105

107-
// 类是函数
106+
// class 是函数 function
108107
alert(typeof User); // function
109108

110-
// ...或者,更确切地说是构造方法
109+
// ...或者,更确切地说,是构造器方法
111110
alert(User === User.prototype.constructor); // true
112111

113-
// User.prototype 中的方法,比如
112+
// 方法在 User.prototype 中,例如
114113
alert(User.prototype.sayHi); // alert(this.name);
115114

116-
// 实际上在原型中有两个方法
115+
// 在原型中实际上有两个方法
117116
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
118117
```
119118

120119
## 不仅仅是语法糖
121120

122-
人们常说 `class` 是 JavaScript 中的语法糖,主要是因为我们可以在没有 `class` 的情况下声明同样的内容
121+
人们常说 `class` 是一个语法糖(旨在使内容更易阅读,但不引入任何新内容的语法),因为我们实际上可以在没有 `class` 的情况下声明相同的内容
123122

124123
```js run
125-
// 以纯函数的重写 User 类
124+
// 用纯函数重写 class User
126125

127126
// 1. 创建构造器函数
128127
function User(name) {
129128
this.name = name;
130129
}
131-
// 任何函数原型默认具有构造器属性
130+
// 任何函数原型默认都具有构造器属性
132131
// 所以,我们不需要创建它
133132

134-
// 2. 向原型中添加方法
133+
// 2. 将方法添加到原型
135134
User.prototype.sayHi = function() {
136135
alert(this.name);
137136
};
138137

139-
// 使用方法
138+
// 用法
140139
let user = new User("John");
141140
user.sayHi();
142141
```
143142

144-
这和定义的结果大致相同。因此,这确实是 `class` 被视为一种定义构造函数及其原型方法的语法糖的理由
143+
这个定义的结果与使用类得到的结果基本相同。因此,这确实是将 `class` 视为一种定义构造函数及其原型方法的语法糖的理由
145144

146-
尽管它们存在重大差异
145+
尽管,它们之间存在着重大差异
147146

148-
1. 首先,通过 `class` 创建的函数是由特殊内部属性标记的 `[[FunctionKind]]:"classConstructor"`所以,相较于手动创建它还是有点不同的
147+
1. 首先,通过 `class` 创建的函数具有特殊的内部属性标记 `[[FunctionKind]]:"classConstructor"`因此,它与手动创建并不完全相同
149148

150149
不像普通函数,调用类构造器时必须要用 `new` 关键词:
151150

@@ -155,10 +154,10 @@ user.sayHi();
155154
}
156155

157156
alert(typeof User); // function
158-
User(); // Error: 没有 ‘new’ 关键词,类构造器 User 无法调用
157+
User(); // Error: Class constructor User cannot be invoked without 'new'
159158
```
160159

161-
此外,大多数 JavaScript 引擎中的类构造函数的字符串表示形式都以 “class 开头
160+
此外,大多数 JavaScript 引擎中的类构造器的字符串表示形式都以 "class..." 开头
162161

163162
```js run
164163
class User {
@@ -169,21 +168,20 @@ user.sayHi();
169168
```
170169

171170
2. 类方法不可枚举。
172-
对于 `"prototype"` 中的所有方法,类定义将 `enumerable` 标记设为 `false。
171+
类定义将 `"prototype"` 中的所有方法的 `enumerable` 标志设置为 `false`
173172

174173
这很好,因为如果我们对一个对象调用 `for..in` 方法,我们通常不希望 class 方法出现。
175174

176-
3. 类默认使用 `use strict`
177-
在类构造函数中的所有方法自动使用严格模式。
178-
175+
3. 类总是使用 `use strict`
176+
在类构造中的所有代码都将自动进入严格模式。
179177

180-
此外,除了它的基础操作外,`class` 语法也带来许多其他功能,我们稍后将会探索它们。
178+
此外,`class` 语法还带来了许多其他功能,我们稍后将会探索它们。
181179

182-
## 类表达式(Class Expression)
180+
## 类表达式
183181

184-
正如函数一样,类可以在另外一个表达式中定义,传递(passed around),返回(returned),调用(assigned)等
182+
就像函数一样,类可以在另外一个表达式中被定义,被传递,被返回,被赋值等。
185183

186-
这里是类表达式的例子
184+
这是一个类表达式的例子
187185

188186
```js
189187
let User = class {
@@ -193,49 +191,49 @@ let User = class {
193191
};
194192
```
195193

196-
类似于命名函数表达式(Named Function Expressions),类表达式可能也可能没有名称
194+
类似于命名函数表达式(Named Function Expressions),类表达式可能也应该有一个名字
197195

198-
如果类表达式有名称,它仅在类内部可见
196+
如果类表达式有名字,那么该名字仅在类内部可见
199197

200198
```js run
201-
// “命名类表达式”
202-
// 规范中没有这样的术语,但是它和命名函数表达式类似
199+
// “命名类表达式(Named Class Expression)
200+
// (规范中没有这样的术语,但是它和命名函数表达式类似)
203201
let User = class *!*MyClass*/!* {
204202
sayHi() {
205-
alert(MyClass); // MyClass 仅在其内部可见
203+
alert(MyClass); // MyClass 这个名字仅在类内部可见
206204
}
207205
};
208206
209207
new User().sayHi(); // 正常运行,显示 MyClass 中定义的内容
210208
211-
alert(MyClass); // 错误,MyClass 在外部不可见
209+
alert(MyClass); // error,MyClass 在外部不可见
212210
```
213211

214212

215-
我们甚至可以“按需”动态创建类,就像这样:
213+
我们甚至可以动态地“按需”创建类,就像这样:
216214

217215
```js run
218216
function makeClass(phrase) {
219-
// 声明并返回类
217+
// 声明一个类并返回它
220218
return class {
221219
sayHi() {
222220
alert(phrase);
223221
};
224222
};
225223
}
226224
227-
// 创建新类
225+
// 创建一个新的类
228226
let User = makeClass("Hello");
229227
230228
new User().sayHi(); // Hello
231229
```
232230

233231

234-
## Getters/setters 及其他 shorthands
232+
## Getters/setters 及其他速记
235233

236-
就像对象字面量,类可能包括 getters/setters,generators,计算属性(computed properties)等。
234+
就像对象字面量,类可能包括 getters/setters,计算属性(computed properties)等。
237235

238-
这是使用 `get/set` 实现 `user.name` 的示例:
236+
这是一个使用 `get/set` 实现 `user.name` 的示例:
239237

240238
```js run
241239
class User {
@@ -266,7 +264,7 @@ class User {
266264
let user = new User("John");
267265
alert(user.name); // John
268266
269-
user = new User(""); // Name too short.
267+
user = new User(""); // Name is too short.
270268
```
271269

272270
类声明在 `User.prototype` 中创建 getters 和 setters,就像这样:
@@ -284,13 +282,14 @@ Object.defineProperties(User.prototype, {
284282
});
285283
```
286284

287-
这是计算属性的例子
285+
这是一个 `[...]` 中有计算属性名称(computed property name)的例子
288286

289287
```js run
290-
function f() { return "sayHi"; }
291-
292288
class User {
293-
[f()]() {
289+
290+
*!*
291+
['say' + 'Hi']() {
292+
*/!*
294293
alert("Hello");
295294
}
296295
@@ -299,53 +298,55 @@ class User {
299298
new User().sayHi();
300299
```
301300

302-
对于 generator 方法,类似的,在它前面添加 `*`
303-
304301
## Class 属性
305302

306303
```warn header="旧的浏览器可能需要 polyfill"
307304
类级别的属性是最近才添加到语言中的。
308305
```
309306

310-
上面的例子中`User` 只有方法。现在我们为其添加属性
307+
在上面的例子中`User` 只有方法。现在我们为其添加一个属性
311308

312309
```js run
313310
class User {
311+
*!*
314312
name = "Anonymous";
313+
*/!*
315314
316315
sayHi() {
317316
alert(`Hello, ${this.name}!`);
318317
}
319318
}
320319
321320
new User().sayHi();
322-
```
323321
324-
属性不在 `User.prototype` 内。相反它是通过 `new` 分别为每个对象创建的。所以,该属性永远不会在同一个类的不同对象之间共享。
322+
alert(User.prototype.sayHi); // 被放在 User.prototype 中
323+
alert(User.prototype.name); // undefined,没有被放在 User.prototype 中
324+
```
325325

326+
`name` 属性没有被放在 `User.prototype` 中。相反,它是在调用构造器之前通过 `new` 分创建的,它是对象自身的属性。
326327

327328
## 总结
328329

329-
基本的类语法看起来是这样的
330+
基本的类语法看起来像这样
330331

331332
```js
332333
class MyClass {
333-
prop = value; // field
334+
prop = value; // 属性
334335
335336
constructor(...) { // 构造器
336337
// ...
337338
}
338339
339-
method(...) {} // 方法
340+
method(...) {} // method
340341
341342
get something(...) {} // getter 方法
342-
set something(...) {} // setter 方法
343+
set something(...) {} // setter 方法
343344
344-
[Symbol.iterator]() {} // 计算 name/symbol 名方法
345+
[Symbol.iterator]() {} // 有计算名称(computed name)的方法(此处为 symbol)
345346
// ...
346347
}
347348
```
348349

349-
技术上来说,`MyClass` 是一个函数(我们提供作为 `constructor` 的那个),而 methodsgetters 和 settors 都被写入 `MyClass.prototype`
350+
技术上来说,`MyClass` 是一个函数(我们提供作为 `constructor` 的那个),而 methodsgetters 和 settors 都被写入了 `MyClass.prototype`
350351

351-
在下一章,我们将会进一步研究类,包括继承在内的其他功能
352+
在下一章,我们将会进一步学习类的相关知识,包括继承和其他功能

1-js/09-classes/01-class/class-user.svg

Lines changed: 1 addition & 29 deletions
Loading

0 commit comments

Comments
 (0)