这是第六章面向对象的程序设计,这一章涉及到一些概念和思想,也是 JavaScript 中很重要的知识点。需要注意的是在第四版中,这部分内容在第八章,在第四版中增加的内容是 Collection Reference Types 和 Iterators and Generatiors。这里还是以第三版为参考。
知识点:
- 1.什么是面向对象?有哪些特点?
- 2.如何创建对象?创建对象的方法进化过程?
- 3.创造出的对象如何自我进化,像人类社会一样不断发展?
1.什么是面向对象?有哪些特点?
首先,这个东西的洋名是 Object Oriented,上一章提到,对象是由引用类型 new 出来的。
const avstar = {
name: "三上悠亚",
jpName: "きとう ももな",
job: "singer",
sing() {
console.log('yep')
}
}
如上,创建了一个名为 きとうももな
的 av 对象,该对象有三个属性分别是 name jpName job,同时,该对象还有一个 sing 的技能,术语叫方法。
在这些属性身上定义了一些特征,这些特征限制了属性的一些权限,分为数据属性和访问器属性。
数据属性有默认值,修改使用 Object.defineProperty()
。
- [[Configurable]]
- [[Enumerable]]
- [[Writable]]
- [[Value]]
访问器属性和数据属性相似,但没有 Value ,它们可以包含非必须的 getter 和 setter 函数。在读取时调用 getter 函数,设置时调用 setter 函数,想到了 Vue 中的计算属性为什么写的是函数而用的时候是按照属性的方式使用的。
- [[Configurable]]
- [[Enumerable]]
- [[Get]]
- [[Set]]
在这里记忆一下代码规范,像以下划线开头的变量 _year 用于表示只能通过对象方法访问的属性。
前面是对属性特性的简单介绍,下面来看如何查看?
可以使用 Object.getOwnPropertyDescriptor()
。
2.如何创建对象
- 工厂模式
- 构造函数
- 原型
- 组合使用构造函数和原型
- 动态原型
- 寄生构造函数
- 稳妥构造函数
- ES6 class
创建对象还不简单?
const person = {
name: "cemcoe",
age: 18"
}
但这种方式用来创建单个对象还好,但如果要创建多个对象可能会变成这个样子:
const person = {
name: "cemcoe",
age: 18"
}
const person2 = {
name: "cemcoe111",
age: 18"
}
const person3 = {
name: "cemcoe222",
age: 18"
}
发现没有,代码有重复的地方,这才3个,如果要搞100个对象,那也太不优雅了。
2.1 工厂模式
就像现代的工业化流程一样,有一种解决方法叫做工厂模式。
function createPerson(name, age) {
const o = new Object()
o.name = name
o.age = age
return o
}
const person = createPerson("cemcoe", 18)
const person2 = createPerson("cemcoe111", 18)
const person3 = createPerson("cemcoe222", 18)
和前面相比重复代码变少了,虽然可以创建多个相似的对象,但是无法知道对象的类型,这种模式有缺陷。
2.2 构造函数
下面是构造函数的模式
function Person(name, age) {
this.name = name
this.age = age
}
const person = new Person("cemcoe", 18)
const person2 = new Person("cemcoe111", 18)
const person3 = new Person("cemcoe222", 18)
和工厂模式相比,构造函数模式没有显式地创建对象,省去了 return 语句。
这里又有一个代码规范,构造函数使用大写字母开头以便和普通函数区分。
重点!!!
看起来少了很多东西,但这个 new 操作符究竟做了什么?
- 创建一个新对象
- 将构造函数的作用域给到新对象,this指向新对象
- 执行构造函数的代码,为对象添加属性
- 返回新对象
person person1 person2 分别保存 Person 的一个不同的实例。这些对象都有一个 constructor 属性,该属性指向 Person,这里就解决了工厂模式无法确定对象类型的问题。
当然,如何要检测对象类型时使用 instanceof 靠谱一些。
person instanceof Person 意思是 person 是 Person 的 instance 吗?
构造函数和普通函数的区别是两种的调用方式不同。
那么构造函数有什么问题内?
问题在于如果在构造函数中为对象的方法时,每次new一个实例方法也会创建方法实例。
这时就轮到原型出场了。
构造函数的问题是,对象中的方法没有办法复用。
下篇接着看。。。
网友评论