第 6 章 面向对象的程序设计

6.1 理解对象

  • 对象的定义:无序属性的集合,其属性可以包含基本值、对象或者函数。
    • 一组键值对,其中值可以是数据或函数

6.1.1 对象的属性

​ 包含两种:数据属性访问器属性

1.数据属性
  • configurable 可配置性(限制 delete 删除属性和Object.defineProperty()方法是否起效。),默认 true
  • enumerable 可列举性,默认 true
  • writable 可写性,默认 true
  • value 值,默认 undefined

使用Object.defineProperty()方法修改这些默认属性。接收三个值:属性所在的对象、属性名、描述符对象

1
2
3
4
5
6
7
8
9
var person = {};
Object.defineProperty(person, "name", {
writable: false,
value: "xu",
});

console.log(person.name); // xu
person.name = "gao"; // 修改无效
console.log(person.name); // xu

使用此方法定义属性如未指定configurableenumerablewritable 将默认false

2.访问器属性

包含两个函数:getter 函数和 setter 函数(这两个函数都是非必需)。读取时调用 getter,访问时调用 setter。

使用Object.defineProperty()方法定义访问器属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var book = {
_year: 2020,
edition: 1,
};

Object.defineProperty(book, "year", {
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2020) {
this._year = newValue;
this.edition += newValue - 2020;
}
},
});

book.year = 2021;
console.log(book.edition); // 2

当 getter 函数和 setter 函数只指定其中一个时,另外一个将不能用。

6.1.2 定义多个属性

Object.defineProperties()方法定义多个属性。接收两个参数: 要添加或修改属性的对象 、第二个参数是一个对象,其属性与第一个参数中的属性一一对应。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var book = {};
Object.defineProperties(book, {
_year: {
// 数据属性
writable: true,
value: 2004,
},
edition: {
// 数据属性
writable: true,
value: 1,
},
year: {
// 访问器属性
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
},
},
});

// 定义了三个属性,每个属性有不同的描述符

6.1.3 读取属性的特性(描述符对象)

Object.getOwnPropertyDescriptor()方法获取描述符,接收两个参数: 属性所在的对象、属性名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var book = {};
Object.defineProperties(book, {
_year: {
// 数据属性
writable: true,
value: 2004,
},
edition: {
// 数据属性
writable: true,
value: 1,
},
year: {
// 访问器属性
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
},
},
});

var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
console.log(descriptor); // {value: 2020, writable: true, enumerable: false, configurable: false}
var descriptor = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor); // {enumerable: false, configurable: false, get: ƒ, set: ƒ}

6.2 创建对象

使用 Object 构造函数或对象字面量方式创建对象。缺点:使用同一个接口创建很多对象时,会产生大量重复代码。解决方案:使用工厂模式的一种变体。

6.2.1 工厂模式