Skip to content
Merged
4 changes: 2 additions & 2 deletions 1-js/03-code-quality/06-polyfills/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ JavaScript 引擎背后的团队关于首先要实现什么有着他们自己想

2. 第二,polyfill。

新的语言特性可能包括新的内置函数和语法构造
transpiler 会重写代码,将语法结构转换为旧的结构。但是对于新的内置函数,需要我们去实现。JavaScript 是一个高度动态化的语言。脚本可以添加/修改任何函数,从而使它们的行为符合现代标准。
新的语言特性可能包括新的内建函数和语法结构
transpiler 会重写代码,将语法结构转换为旧的结构。但是对于新的内建函数,需要我们去实现。JavaScript 是一个高度动态化的语言。脚本可以添加/修改任何函数,从而使它们的行为符合现代标准。

更新/添加新函数的脚本称为 “polyfill”。它“填补”了缺口,并添加了缺少的实现。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ importance: 5

它创建的对象应该:

- 将“当前 value”存储在属性 `value` 中。起始值被设置到构造函数的 `startingValue` 参数
- 将“当前 value”存储在属性 `value` 中。起始值被设置到构造器 `startingValue` 的参数
- `read()` 方法应该使用 `prompt` 来读取一个新的数字,并将其添加到 `value` 中。

换句话说,`value` 属性是所有用户输入值与初始值 `startingValue` 的总和。
Expand Down
24 changes: 12 additions & 12 deletions 1-js/04-object-basics/06-constructor-new/article.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 构造函数和操作符 "new"
# 构造器和操作符 "new"

常规的 `{...}` 语法允许创建一个对象。但是我们经常需要创建许多类似的对象,例如多个用户或菜单项等。

Expand Down Expand Up @@ -62,9 +62,9 @@ let user = {

现在,如果我们想创建其他用户,我们可以调用 `new User("Ann")`,`new User("Alice")` 等。比每次都使用字面量创建要短得多,而且更易于阅读。

这是构造函数的主要目的 — 实现可重用的对象创建代码。
这是构造器的主要目的 — 实现可重用的对象创建代码。

让我们再强调一遍 — 从技术上讲,任何函数都可以用作构造函数。即:任何函数都可以通过 `new` 来运行,它会执行上面的算法。“首字母大写”是一个共同的约定,以明确表示一个函数将被使用 `new` 来运行。
让我们再强调一遍 — 从技术上讲,任何函数都可以用作构造器。即:任何函数都可以通过 `new` 来运行,它会执行上面的算法。“首字母大写”是一个共同的约定,以明确表示一个函数将被使用 `new` 来运行。

````smart header="new function() { ... }"
如果我们有许多行用于创建单个复杂对象的代码,我们可以将它们封装在构造函数中,像这样:
Expand All @@ -80,10 +80,10 @@ let user = new function() {
};
```

构造函数不能被再次调用,因为它不保存在任何地方,只是被创建和调用。因此,这个技巧旨在封装构建单个对象的代码,而无需将来重用。
构造器不能被再次调用,因为它不保存在任何地方,只是被创建和调用。因此,这个技巧旨在封装构建单个对象的代码,而无需将来重用。
````

## 双语法构造函数:new.target
## 构造器模式测试:new.target

```smart header="进阶内容"
本节涉及的语法内容很少使用,除非你想了解所有内容,否则你可以直接跳过该语法。
Expand All @@ -109,7 +109,7 @@ new User(); // function User { ... }
*/!*
```

它可以被用在函数内部,来判断该函数是被通过 `new` 调用的“构造函数模式”,还是没被通过 `new` 调用的“常规模式”。
它可以被用在函数内部,来判断该函数是被通过 `new` 调用的“构造器模式”,还是没被通过 `new` 调用的“常规模式”。

我们也可以让 `new` 调用和常规调用做相同的工作,像这样:

Expand All @@ -130,9 +130,9 @@ alert(john.name); // John

不过,到处都使用它并不是一件好事,因为省略了 `new` 使得很难观察到代码中正在发生什么。而通过 `new` 我们都可以知道这创建了一个新对象。

## 构造函数的 Return
## 构造器的 return

通常,构造函数没有 `return` 语句。它们的任务是将所有必要的东西写入 `this`,并自动转换为结果。
通常,构造器没有 `return` 语句。它们的任务是将所有必要的东西写入 `this`,并自动转换为结果。

但是,如果这有一个 `return` 语句,那么规则就简单了:

Expand Down Expand Up @@ -167,7 +167,7 @@ function SmallUser() {
alert( new SmallUser().name ); // John
```

通常构造函数没有 `return` 语句。这里我们主要为了完整性而提及返回对象的特殊行为。
通常构造器没有 `return` 语句。这里我们主要为了完整性而提及返回对象的特殊行为。

````smart header="省略括号"
顺便说一下,如果没有参数,我们可以省略 `new` 后的括号:
Expand All @@ -181,7 +181,7 @@ let user = new User();
这里省略括号不被认为是一种“好风格”,但是规范允许使用该语法。
````

## 构造函数中的方法
## 构造器中的方法

使用构造函数来创建对象会带来很大的灵活性。构造函数可能有一些参数,这些参数定义了如何构造对象以及要放入什么。

Expand Down Expand Up @@ -216,15 +216,15 @@ john = {

## 总结

- 构造函数,或简称构造器,就是常规函数,但大家对于构造函数有个共同的约定,就是其命名首字母要大写。
- 构造函数,或简称构造器,就是常规函数,但大家对于构造器有个共同的约定,就是其命名首字母要大写。
- 构造函数只能使用 `new` 来调用。这样的调用意味着在开始时创建了空的 `this`,并在最后返回填充了值的 `this`。

我们可以使用构造函数来创建多个类似的对象。

JavaScript 为许多内置的对象提供了构造函数:比如日期 `Date`、集合 `Set` 以及其他我们计划学习的内容。

```smart header="对象,我们还会回来哒!"
在本章中,我们只介绍了关于对象和构造函数的基础知识。它们对于我们在下一章中,学习更多关于数据类型和函数的相关知识非常重要。
在本章中,我们只介绍了关于对象和构造器的基础知识。它们对于我们在下一章中,学习更多关于数据类型和函数的相关知识非常重要。

在我们学习了那些之后,我们将回到对象,在 <info:prototypes> 和 <info:classes> 章节中深入介绍它们。
```
2 changes: 1 addition & 1 deletion 1-js/05-data-types/01-primitives-methods/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ alert( n.toFixed(2) ); // 1.23
我们将在后面 <info:number> 和 <info:string> 章节中看到更多具体的方法。


````warn header="构造函数 `String/Number/Boolean` 仅供内部使用"
````warn header="构造器 `String/Number/Boolean` 仅供内部使用"
像 Java 这样的一些语言允许我们使用 `new Number(1)` 或 `new Boolean(false)` 等语法,明确地为原始类型创建“对象包装器”。

在 JavaScript 中,由于历史原因,这也是可以的,但极其 **不推荐**。因为这样会出问题。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ importance: 5

# Counter 对象

这里通过构造器函数创建了一个 counter 对象。
这里通过构造函数创建了一个 counter 对象。

它能正常工作吗?它会显示什么呢?

Expand Down
2 changes: 1 addition & 1 deletion 1-js/06-advanced-functions/10-bind/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ setTimeout(f, 1000); // 丢失了 user 上下文

这个需求很典型 —— 我们想将一个对象方法传递到别的地方(这里 —— 传递到调度程序),然后在该位置调用它。如何确保在正确的上下文中调用它?

## 解决方案 1:包装层
## 解决方案 1:包装器

最简单的解决方案是使用一个包装函数:

Expand Down
2 changes: 1 addition & 1 deletion 1-js/06-advanced-functions/12-arrow-functions/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ group.showList();
但箭头函数就没事,因为它们没有 `this`。

```warn header="不能对箭头函数进行 `new` 操作"
不具有 `this` 自然也就意味着另一个限制:箭头函数不能用作构造函数。不能用 `new` 调用它们。
不具有 `this` 自然也就意味着另一个限制:箭头函数不能用作构造器(constructor)。不能用 `new` 调用它们。
```

```smart header="箭头函数 VS bind"
Expand Down
8 changes: 4 additions & 4 deletions 1-js/08-prototypes/02-function-prototype/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ alert( rabbit.eats ); // true
如果在创建之后,`F.prototype` 属性有了变化(`F.prototype = <another object>`),那么通过 `new F` 创建的新对象也将随之拥有新的对象作为 `[[Prototype]]`,但已经存在的对象将保持旧有的值。
```

## 默认的 F.prototype,构造函数属性
## 默认的 F.prototype,构造器属性

每个函数都有 `"prototype"` 属性,即使我们没有提供它。

Expand Down Expand Up @@ -88,7 +88,7 @@ alert(rabbit.constructor == Rabbit); // true (from prototype)

![](rabbit-prototype-constructor.svg)

我们可以使用 `constructor` 属性来创建一个新对象,该对象使用与现有对象相同的构造函数
我们可以使用 `constructor` 属性来创建一个新对象,该对象使用与现有对象相同的构造器

像这样:

Expand All @@ -105,7 +105,7 @@ let rabbit2 = new rabbit.constructor("Black Rabbit");
*/!*
```

当我们有一个对象,但不知道它使用了哪个构造函数(例如它来自第三方库),并且我们需要创建另一个类似的对象时,用这种方法就很方便。
当我们有一个对象,但不知道它使用了哪个构造器(例如它来自第三方库),并且我们需要创建另一个类似的对象时,用这种方法就很方便。

但是,关于 `"constructor"` 最重要的是……

Expand Down Expand Up @@ -172,4 +172,4 @@ let user = {
};
```

默认情况下,所有函数都有 `F.prototype = {constructor:F}`,所以我们可以通过访问它的 `"constructor"` 属性来获取一个对象的构造函数
默认情况下,所有函数都有 `F.prototype = {constructor:F}`,所以我们可以通过访问它的 `"constructor"` 属性来获取一个对象的构造器
6 changes: 3 additions & 3 deletions 1-js/08-prototypes/03-native-prototypes/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ alert(Object.prototype.__proto__); // null

其他内建对象,像 `Array`、`Date`、`Function` 及其他,都在 prototype 上挂载了方法。

例如,当我们创建一个数组 `[1, 2, 3]`,在内部会默认使用 `new Array()` 构造函数。因此 `Array.prototype` 变成了这个数组的 prototype,并为这个数组提供数组的操作方法。这样内存的存储效率是很高的。
例如,当我们创建一个数组 `[1, 2, 3]`,在内部会默认使用 `new Array()` 构造器。因此 `Array.prototype` 变成了这个数组的 prototype,并为这个数组提供数组的操作方法。这样内存的存储效率是很高的。

按照规范,所有的内建原型顶端都是 `Object.prototype`。这就是为什么有人说“一切都从对象继承而来”。

Expand Down Expand Up @@ -86,7 +86,7 @@ alert(arr); // 1,2,3 <-- Array.prototype.toString 的结果

![](console_dir_array.png)

其他内建对象也以同样的方式运行。即使是函数 —— 它们是内建构造函数 `Function` 的对象,并且它们的方法(`call`/`apply` 及其他)都取自 `Function.prototype`。函数也有自己的 `toString` 方法。
其他内建对象也以同样的方式运行。即使是函数 —— 它们是内建构造器 `Function` 的对象,并且它们的方法(`call`/`apply` 及其他)都取自 `Function.prototype`。函数也有自己的 `toString` 方法。

```js run
function f() {}
Expand All @@ -99,7 +99,7 @@ alert(f.__proto__.__proto__ == Object.prototype); // true, inherit from objects

最复杂的事情发生在字符串、数字和布尔值上。

正如我们记忆中的那样,它们并不是对象。但是如果我们试图访问它们的属性,那么临时包装器对象将会通过内建的构造函数 `String`、`Number` 和 `Boolean` 被创建。它们提供给我们操作字符串、数字和布尔值的方法然后消失。
正如我们记忆中的那样,它们并不是对象。但是如果我们试图访问它们的属性,那么临时包装器对象将会通过内建的构造器 `String`、`Number` 和 `Boolean` 被创建。它们提供给我们操作字符串、数字和布尔值的方法然后消失。

这些对象对我们来说是无形地创建出来的。大多数引擎都会对其进行优化,但是规范中描述的就是通过这种方式。这些对象的方法也驻留在它们的 prototype 中,可以通过 `String.prototype`、`Number.prototype` 和 `Boolean.prototype` 进行获取。

Expand Down
2 changes: 1 addition & 1 deletion 1-js/09-classes/01-class/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ let user = new User("John");
user.sayHi();
```

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

尽管,它们之间存在着重大差异:

Expand Down
4 changes: 2 additions & 2 deletions 1-js/09-classes/02-class-inheritance/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ let rabbit = new Rabbit("White Rabbit", 10); // Error: this is not defined.

当然,本文会给出一个解释。让我们深入细节,这样你就可以真正地理解发生了什么。

在 JavaScript 中,继承类(所谓的“派生构造函数”,英文为 "derived constructor")的构造函数与其他函数之间是有区别的。派生的构造函数具有特殊的内部属性 `[[ConstructorKind]]:"derived"`。这是一个特殊的内部标签。
在 JavaScript 中,继承类(所谓的“派生构造器”,英文为 "derived constructor")的构造函数与其他函数之间是有区别的。派生构造器具有特殊的内部属性 `[[ConstructorKind]]:"derived"`。这是一个特殊的内部标签。

该标签会影响它的 `new` 行为:

Expand Down Expand Up @@ -524,7 +524,7 @@ rabbit.eat(); // 错误调用 super(因为这里没有 [[HomeObject]])
- 在使用 `this` 之前,我们必须在 `Child` 的 constructor 中将父 constructor 调用为 `super()`。
3. 重写一个方法:
- 我们可以在一个 `Child` 方法中使用 `super.method()` 来调用 `Parent` 方法。
4. 内部工作
4. 内部
- 方法在内部的 `[[HomeObject]]` 属性中记住了它们的类/对象。这就是 `super` 如何解析父方法的。
- 因此,将一个带有 `super` 的方法从一个对象复制到另一个对象是不安全的。

Expand Down
2 changes: 1 addition & 1 deletion 1-js/09-classes/03-static-properties-methods/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ User.staticMethod = function() {
User.staticMethod(); // true
```

在 `User.staticMethod()` 调用中的 `this` 的值是类构造函数 `User` 自身(“点符号前面的对象”规则)。
在 `User.staticMethod()` 调用中的 `this` 的值是类构造器 `User` 自身(“点符号前面的对象”规则)。

通常来说,静态方法用来属于该类,但不属于该类的任何热定对象的函数。

Expand Down
6 changes: 3 additions & 3 deletions 1-js/10-error-handling/1-try-catch/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ throw <error object>

技术上讲,我们可以将任何东西用作 error 对象。甚至可以时一个原始类型数据,例如数字或字符串,但最好使用对象,最好使用具有具有 `name` 和 `message` 属性的对象(某种程度上保持与内建 error 的兼容性)。

JavaScript 中有很多内建的标准 error 的构造函数:`Error`,`SyntaxError`,`ReferenceError`,`TypeError` 等。我们也可以使用它们来创建 error 对象。
JavaScript 中有很多内建的标准 error 的构造器:`Error`,`SyntaxError`,`ReferenceError`,`TypeError` 等。我们也可以使用它们来创建 error 对象。

它们的语法是:

Expand All @@ -278,7 +278,7 @@ let error = new ReferenceError(message);
// ...
```

对于内建的 error(不是对于其他任何对象,仅仅是对于 error),`name` 属性刚好就是构造函数的名字。`message` 则来自于参数(argument)。
对于内建的 error(不是对于其他任何对象,仅仅是对于 error),`name` 属性刚好就是构造器的名字。`message` 则来自于参数(argument)。

例如:

Expand Down Expand Up @@ -659,7 +659,7 @@ try {
Error 对象包含下列属性:

- `message` — 人类可读的 error 信息。
- `name` — 具有 error 名称的字符串(Error 构造函数的名称)。
- `name` — 具有 error 名称的字符串(Error 构造器的名称)。
- `stack`(没有标准,但得到了很好的支持)— Error 发生时的调用栈。

如果我们不需要 error 对象,我们可以通过使用 `catch {` 而不是 `catch(err) {` 来省略它。
Expand Down
6 changes: 3 additions & 3 deletions 1-js/11-async/02-promise-basics/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

这种类比并不十分准确,因为 JavaScipt 的 promise 比简单的订阅列表更加复杂:它们还拥有其他的功能和局限性。但以此开始挺好的。

Promise 对象的构造函数(constructor)语法如下:
Promise 对象的构造器(constructor)语法如下:

```js
let promise = new Promise(function(resolve, reject) {
Expand All @@ -33,7 +33,7 @@ let promise = new Promise(function(resolve, reject) {

所以总结一下就是:executor 会自动运行并尝试执行一项工作。尝试结束后,如果成功则调用 `resolve`,如果出现 error 则调用 `reject`。

由 `new Promise` 构造函数(constructor)返回的 `promise` 对象具有以下内部属性:
由 `new Promise` 构造器返回的 `promise` 对象具有以下内部属性:

- `state` — 最初是 `"pending"`,然后在 `resolve` 被调用时变为 `"fulfilled"`,或者在 `reject` 被调用时变为 `"rejected"`。
- `result` — 最初是 `undefined`,然后在 `resolve(value)` 被调用时变为 `value`,或者在 `reject(error)` 被调用时变为 `error`。
Expand All @@ -44,7 +44,7 @@ let promise = new Promise(function(resolve, reject) {

稍后我们将看到“粉丝”如何订阅这些更改。

下面是一个 promise 构造函数(constructor)和一个简单的 executor 函数,该 executor 函数具有包含时间(即 `setTimeout`)的“生产者代码”:
下面是一个 promise 构造器和一个简单的 executor 函数,该 executor 函数具有包含时间(即 `setTimeout`)的“生产者代码”:

```js run
let promise = new Promise(function(resolve, reject) {
Expand Down
2 changes: 1 addition & 1 deletion 1-js/99-js-misc/01-proxy/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ alert(proxy.data); // Error(revoked)

## 总结

`Proxy` 是对象的包装,将代理上的操作转发到对象,并可以选择捕获其中一些操作。
`Proxy` 是对象的包装器,将代理上的操作转发到对象,并可以选择捕获其中一些操作。

它可以包装任何类型的对象,包括类和函数。

Expand Down
2 changes: 1 addition & 1 deletion 1-js/99-js-misc/02-eval/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ let f = new Function('a', 'alert(a)');
f(5); // 5
```

我们在 <info:new-function> 一章中对 `new Function` 构造进行了详细说明。`new Function` 从字符串创建一个函数,并且也是在全局作用域中的。所以它无法访问局部变量。但是,正如上面的示例一样,将它们作为参数进行显式传递要清晰得多。
我们在 <info:new-function> 一章中对 `new Function` 构造器进行了详细说明。`new Function` 从字符串创建一个函数,并且也是在全局作用域中的。所以它无法访问局部变量。但是,正如上面的示例一样,将它们作为参数进行显式传递要清晰得多。

## 总结

Expand Down