0.关系图【重点】:
关系总结:每一个构造函数都有一个属性,叫prototype,指向原型对象。
每个实例对象都有个非标准的--proto--指向原型对象
每个原型对象有个constructor指回构造函数
在继承的时候,经常会使用 constructor指回去,prototype.constructor仅仅可以用于识别对象是由哪个构造函数初始化的,仅此而已
1.原型(原型对象)
1.1 是什么?
是构造函数的一个属性,它的数据类型是对象
1.2 作用
共享方法,节省内存(当然也可以存别的)实现继承与扩展对象
原型对象对应的构造函数的实例方法或属性不存在时会去查找原型对象
结合构造函数原型的特征,实际开发重往往会将封装的功能函数添加到原型对象中。
2.原型链
2.1 是什么?
简洁答案:原型连起来的结构
扯一扯的答案:
当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去 prototype 里找这个属性,这个 prototype 又会有自己的 prototype,于是就这样一直找下去, 也就是我们平时所说的原型链的概念
2.2 作用?
提供查找成员的机制
2.3 特点
JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己 的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变
3.构造函数
3.1 是什么?
本质上依旧是函数,一般与new结合使用才有意义
构造函数相当于一个"模子",能够像字面量那样创建出对象来,所不同的是借助构造函数创建出来的实例对象之间是彼此不影响的。
3.2 作用?
构造函数是专门用于创建对象的函数,如果一个函数使用 new 关键字调用,那么这个函数就是构造函数。
可以实现用它实现继承
3.3总结
- 构造函数体现了面向对象的封装特性
- 构造函数实例创建的对象彼此独立、互不影响
- 命名空间式的封装无法保证数据的独立性
- this指向实例对象
4.继承
4.1 是什么?
子类继承父类
继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。
龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义
4.2 语法
es6前:
extends :用于申明一个类为子类,可以继承另外一个类
class Son extends Father {}
super 调用父类的方法
如果子类有自己的constructor,那么必须通过super调用父类的方法 (注意位置先用super后面再用this,super里面吧父亲里面的变量写上) super:调用父类的构造函数 注意里面变量都带上
类 class es6
class是构造函数的语法糖;构造函数是class的语法盐
4.3 继承的代码实现示例
<script> // 所有人 function Person() { // 人的特征 this.arms = 2; this.legs = 2; this.eyes = 2; // 人的行为 this.walk = function () {} this.sing = function () {} this.sleep = function () {} } // 封装中国人的行为特征 function Chinese() { // 中国人的特征 this.skin = 'yellow'; this.language = '中文'; } // 封装日本人的行为特征 function Japanese() { // 日本人的特征 this.skin = 'yellow'; this.language = '日文'; } // human 是构造函数 Person 的实例 let human = new Person(); // 中国人 Chinese.prototype = human; Chinese.prototype.constructor = Chinese; // 日本人 Japanese.prototype = human; Japanese.prototype.constructor = Japanese; </script>
5.实例对象
实例化的原理:
new的时候,做了如下几件事:
首先在内存当中创建一个新对象
之后this指向这个对象
指向构造函数
返回这个对象