1
0
mirror of https://github.com/apachecn/eloquent-js-3e-zh.git synced 2025-05-23 11:52:20 +00:00
This commit is contained in:
wizardforcel 2018-05-04 21:06:43 +08:00
parent f304d920b4
commit 1a0830d30f

28
6.md
View File

@ -20,7 +20,7 @@
虽然没有人真正同意其精确定义,但面向对象编程已经成为了许多编程语言的设计,包括 JavaScript 在内。 本章将描述这些想法在 JavaScript 中的应用方式。 虽然没有人真正同意其精确定义,但面向对象编程已经成为了许多编程语言的设计,包括 JavaScript 在内。 本章将描述这些想法在 JavaScript 中的应用方式。
### 封装 ## 封装
面向对象编程的核心思想是将程序分成小型片段,并让每个片段负责管理自己的状态。 面向对象编程的核心思想是将程序分成小型片段,并让每个片段负责管理自己的状态。
@ -36,7 +36,7 @@
将接口与实现分离是一个好主意。 它通常被称为封装encapsulation 将接口与实现分离是一个好主意。 它通常被称为封装encapsulation
### 6.2 方法 ## 方法
方法不过是持有函数值的属性。 这是一个简单的方法: 方法不过是持有函数值的属性。 这是一个简单的方法:
@ -90,7 +90,7 @@ normalize.call({coords: [0, 2, 3], length: 5});
如果我使用`function`关键字将参数写入`map`,则代码将不起作用。 如果我使用`function`关键字将参数写入`map`,则代码将不起作用。
### 原型 ## 原型
我们来仔细看看以下这段代码。 我们来仔细看看以下这段代码。
@ -151,7 +151,7 @@ killerRabbit.speak("SKREEEE!");
原型对象`protoRabbit`是一个容器,用于包含所有兔子对象的公有属性。每个独立的兔子对象(比如`killerRabbit`)可以包含其自身属性(比如本例中的`type`属性),也可以派生其原型对象中公有的属性。 原型对象`protoRabbit`是一个容器,用于包含所有兔子对象的公有属性。每个独立的兔子对象(比如`killerRabbit`)可以包含其自身属性(比如本例中的`type`属性),也可以派生其原型对象中公有的属性。
### ## 类
JavaScript 的原型系统可以解释为对一种面向对象的概念称为类class的某种非正式实现。 类定义了对象的类型的形状 - 它具有什么方法和属性。 这样的对象被称为类的实例instance JavaScript 的原型系统可以解释为对一种面向对象的概念称为类class的某种非正式实现。 类定义了对象的类型的形状 - 它具有什么方法和属性。 这样的对象被称为类的实例instance
@ -227,7 +227,7 @@ console.log(object.getWord());
// → hello // → hello
``` ```
### 覆盖派生的属性 ## 覆盖派生的属性
将属性添加到对象时,无论它是否存在于原型中,该属性都会添加到对象本身中。 如果原型中已经有一个同名的属性,该属性将不再影响对象,因为它现在隐藏在对象自己的属性后面。 将属性添加到对象时,无论它是否存在于原型中,该属性都会添加到对象本身中。 如果原型中已经有一个同名的属性,该属性将不再影响对象,因为它现在隐藏在对象自己的属性后面。
@ -267,7 +267,7 @@ console.log(Object.prototype.toString.call([1, 2]));
// → [object Array] // → [object Array]
``` ```
### 映射 ## 映射
我们在上一章中看到了映射map这个词用于一个操作通过对元素应用函数来转换数据结构。 令人困惑的是,在编程时,同一个词也被用于相关而不同的事物。 我们在上一章中看到了映射map这个词用于一个操作通过对元素应用函数来转换数据结构。 令人困惑的是,在编程时,同一个词也被用于相关而不同的事物。
@ -325,7 +325,7 @@ console.log({x: 1}.hasOwnProperty("toString"));
// → false // → false
``` ```
### 6.8 多态 ## 多态
当你调用一个对象的`String`函数(将一个值转换为一个字符串)时,它会调用该对象的`toString`方法来尝试从它创建一个有意义的字符串。 我提到一些标准原型定义了自己的`toString`版本,因此它们可以创建一个包含比`"[object Object]"`有用信息更多的字符串。 你也可以自己实现。 当你调用一个对象的`String`函数(将一个值转换为一个字符串)时,它会调用该对象的`toString`方法来尝试从它创建一个有意义的字符串。 我提到一些标准原型定义了自己的`toString`版本,因此它们可以创建一个包含比`"[object Object]"`有用信息更多的字符串。 你也可以自己实现。
@ -344,7 +344,7 @@ console.log(String(blackRabbit));
我在第四章中提到`for/of`循环可以遍历几种数据结构。 这是多态性的另一种情况 - 这样的循环期望数据结构公开的特定接口,数组和字符串是这样。 你也可以将这个接口添加到你自己的对象中! 但在我们实现它之前,我们需要知道什么是符号。 我在第四章中提到`for/of`循环可以遍历几种数据结构。 这是多态性的另一种情况 - 这样的循环期望数据结构公开的特定接口,数组和字符串是这样。 你也可以将这个接口添加到你自己的对象中! 但在我们实现它之前,我们需要知道什么是符号。
### 符号 ## 符号
多个接口可能为不同的事物使用相同的属性名称。 例如,我可以定义一个接口,其中`toString`方法应该将对象转换为一段纱线。 一个对象不可能同时满足这个接口和`toString`的标准用法。 多个接口可能为不同的事物使用相同的属性名称。 例如,我可以定义一个接口,其中`toString`方法应该将对象转换为一段纱线。 一个对象不可能同时满足这个接口和`toString`的标准用法。
@ -574,7 +574,7 @@ console.log(matrix.get(2, 3));
尽管封装和多态可用于将代码彼此分离,从而减少整个程序的耦合,但继承从根本上将类连接在一起,从而产生更多的耦合。 继承一个类时,比起单纯使用它,你通常必须更加了解它如何工作。 继承可能是一个有用的工具,并且我现在在自己的程序中使用它,但它不应该成为你的第一个工具,你可能不应该积极寻找机会来构建类层次结构(类的家族树)。 尽管封装和多态可用于将代码彼此分离,从而减少整个程序的耦合,但继承从根本上将类连接在一起,从而产生更多的耦合。 继承一个类时,比起单纯使用它,你通常必须更加了解它如何工作。 继承可能是一个有用的工具,并且我现在在自己的程序中使用它,但它不应该成为你的第一个工具,你可能不应该积极寻找机会来构建类层次结构(类的家族树)。
### 6.12 `instanceof`运算符 ## `instanceof`运算符
在有些时候了解某个对象是否继承自某个特定类也是十分有用的。JavaScript 为此提供了一个二元运算符,名为`instanceof` 在有些时候了解某个对象是否继承自某个特定类也是十分有用的。JavaScript 为此提供了一个二元运算符,名为`instanceof`
@ -592,7 +592,7 @@ console.log([1] instanceof Array);
该运算符会浏览所有继承类型。所以`SymmetricMatrix``Matrix`的一个实例。 该运算符也可以应用于像`Array`这样的标准构造器。 几乎每个对象都是`Object`的一个实例。 该运算符会浏览所有继承类型。所以`SymmetricMatrix``Matrix`的一个实例。 该运算符也可以应用于像`Array`这样的标准构造器。 几乎每个对象都是`Object`的一个实例。
### 本章小结 ## 本章小结
对象不仅仅持有它们自己的属性。对象中有另一个对象:原型,只要原型中包含了属性,那么根据原型构造出来的对象也就可以看成包含了相应的属性。简单对象直接以`Object.prototype`作为原型。 对象不仅仅持有它们自己的属性。对象中有另一个对象:原型,只要原型中包含了属性,那么根据原型构造出来的对象也就可以看成包含了相应的属性。简单对象直接以`Object.prototype`作为原型。
@ -608,9 +608,9 @@ console.log([1] instanceof Array);
实现多个类,它们仅在一些细节上有所不同的时,将新类编写为现有类的子类,继承其一部分行为会很有帮助。 实现多个类,它们仅在一些细节上有所不同的时,将新类编写为现有类的子类,继承其一部分行为会很有帮助。
### 6.14 习题 ## 习题
#### 6.14.1 向量类型 ### 向量类型
编写一个构造器`Vec`,在二维空间中表示数组。该函数接受两个数字参数`x``y`,并将其保存到对象的同名属性中。 编写一个构造器`Vec`,在二维空间中表示数组。该函数接受两个数字参数`x``y`,并将其保存到对象的同名属性中。
@ -629,7 +629,7 @@ console.log(new Vec(3, 4).length);
// → 5 // → 5
``` ```
#### 分组 ### 分组
标准的 JavaScript 环境提供了另一个名为`Set`的数据结构。 像`Map`的实例一样,集合包含一组值。 与`Map`不同,它不会将其他值与这些值相关联 - 它只会跟踪哪些值是该集合的一部分。 一个值只能是一个集合的一部分 - 再次添加它没有任何作用。 标准的 JavaScript 环境提供了另一个名为`Set`的数据结构。 像`Map`的实例一样,集合包含一组值。 与`Map`不同,它不会将其他值与这些值相关联 - 它只会跟踪哪些值是该集合的一部分。 一个值只能是一个集合的一部分 - 再次添加它没有任何作用。
@ -656,7 +656,7 @@ console.log(group.has(10));
// → false // → false
``` ```
#### 可迭代分组 ### 可迭代分组
使上一个练习中的`Group`类可迭代。 如果你不清楚接口的确切形式,请参阅本章前面迭代器接口的章节。 使上一个练习中的`Group`类可迭代。 如果你不清楚接口的确切形式,请参阅本章前面迭代器接口的章节。