面向对象编程
基本概念
对象到底是什么,可以从两次层次来理解。
(1) 对象是具体事物的抽象。
一本书、一辆汽车、一个人都可以是对象,当实物被抽象成对象,实物之间的关系就变成了对象之间的关系,从而就可以模拟现实情况,针对对象进行编程。
(2) 对象是无序键值对的集合,其属性可以包含基本值、对象或者函数
每个对象都是基于一个引用类型创建的,这些类型可以是系统内置的原生类型,也可以是开发人员自定义的类型。
面向对象
面向对象编程 —— Object Oriented Programming,简称 OOP ,是一种编程开发思想。
在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工,可以完成接受信息、处理数据、发出信息等任务。
因此,面向对象编程具有灵活、代码可复用、高度模块化等特点,容易维护和开发,比起由一系列函数或指令组成的传统的过程式编程(procedural programming),更适合多人合作的大型软件项目。
面向对象与面向过程:
- 面向过程就是亲历亲为,事无巨细,有条不紊,面向过程是解决问题的一种思维方式,(执行者的角度)
- 关注点在于解决问题的过程(先xx,然后xx,在xx);
- 面向对象就是找一个对象,让它去做这件事情(指挥者的角度)
- 关注点在找到能解决问题的对象上。
- 面向对象不是面向过程的替代,而是面向过程的封装
面向对象的特性:
- 封装性
- 将功能的具体实现,全部封装到对象的内部,外界使用对象时,只需要关注对象提供的方法如何使用,而不需要关心对象的内部具体实现,这就是封装。
- 继承性
- 在js中,继承的概念很简单,一个对象没有的一些属性和方法,另外一个对象有,拿过来用,就实现了继承。
- 注意:在其他语言里面,继承是类与类之间的关系,在js中,是对象与对象之间的关系。
- [多态性]
- 多态是在强类型的语言中才有的。js是弱类型语言,所以JS不支持多态
创建对象的方式
内置构造函数创建
可以直接通过 new Object() 创建:
1 | //在js中,对象有动态特性,可以随时的给一个对象增加属性或者删除属性。 |
缺点:麻烦,每个属性都需要添加。
对象字面量创建
1 | var person = { |
缺点:如果要批量生成多个对象,代码很冗余
工厂函数
可以写一个函数,解决代码重复问题:
1 | function createPerson (name, age) { |
然后生成实例对象:
1 | var p1 = createPerson('Jack', 18) |
缺点:但却没有解决对象识别的问题,创建出来的对象都是Object类型的。
构造函数
构造函数是一个函数,用于实例化对象,需要配合new操作符使用。
1 | function Person (name, age) { |
而要创建 Person 实例,则必须使用 new 操作符。
以这种方式调用构造函数会经历以下 4 个步骤:
- 创建一个新对象
- 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)
- 执行构造函数中的代码
- 返回新对象
构造函数需要配合new操作符使用才有意义,构造函数首字母都应该大写
构造函数的缺点
使用构造函数带来的最大的好处就是创建对象更方便了,但是其本身也存在一个浪费内存的问题:
1 | function Person (name, age) { |
解决方案:将方法提取到外面
1 | function sayHello() { |
缺点:会暴漏很多的函数,容易造成全局变量污染。
原型
原型基本概念
Javascript 规定,每一个函数都有一个 prototype 属性,指向另一个对象。
这个对象的所有属性和方法,都会被构造函数的实例继承。
这也就意味着,我们可以把所有对象实例需要共享的属性和方法直接定义在 prototype 对象上。
1 | function Person (name, age) { |
这时所有实例的 type 属性和 sayName() 方法,其实都是同一个内存地址
构造函数、实例、原型三者之间的关系
构造函数:构造函数就是一个函数,配合new可以新建对象。
实例:通过构造函数实例化出来的对象我们把它叫做构造函数的实例。一个构造函数可以有很多实例。
原型:每一个构造函数都有一个属性prototype,函数的prototype属性值就是原型。通过构造函数创建出来的实例能够直接使用原型上的属性和方法。
思考:内置对象中,有很多的方法,这些方法存在哪里?
__proto__
任意一个对象,都会有__proto__属性,这个属性指向了构造函数的prototype属性,也就是原型对象。
获取原型对象:
- 通过
构造函数.prototype可以获取 - 通过
实例.__proto__可以获取(隐式原型) - 它们指向了同一个对象
构造函数.prototype === 实例.__proto__
注意:__proto__是浏览器的一个隐藏(私有)属性,IE浏览器不支持,不要通过它来修改原型里的内容,如果要修改原型中的内容,使用构造函数.prototype去修改
constructor属性
默认情况下,原型对象中只包含了一个属性:constructor,constructor属性指向了当前的构造函数。
原型链
原型链概念
任何一个对象,都有原型对象,原型对象本身又是一个对象,所以原型对象也有自己的原型对象,这样一环扣一环就形成了一个链式结构,我们把这个链式结构称为:原型链。
**Object.prototype是原型链的尽头,Object.prototype的原型是null **


