1. 定义
-
原型是 function 对象的一个属性, 它定义了构造函数制造出的对象的公共祖先
通过该构造函数产生的对象, 可以继承该原型的属性和方法
备注: 原型也是对象, 相当于父类 ( 更确切来说是模板 ) -
举个例子
1.构造模板的构造函数
function Parent(){};
2.派生类的构造函数
function Child(){};
3.构造模板parent1
var parent1 = new Parent();
4.导入模板的属性和方法于子类构造函数当中
Child.prototype = parent1;
5.子类构造函数构造出来的对象child1会具有parent1中的属性和方法
var child1 = new Child();
- 如下所示
新建出来的对象 child1 的 __proto__ 属性指向了模板 model,
当调用对象属性时, 若目标属性不存在于该对象之中, 就会自动去原型中寻找,
直到寻找到最高父类 Object() 的原型为止
2. 给原型增加属性的方法
(1) 直接增加
- 可以直接用
子类构造函数.prototype.newatr = newatrvalue
来增加原型的属性
Constructor.prototype.newatr = newatrvalue
-
备注
新增属性必须赋值才会出现在原型中 -
如下所示
给构造函数 Child 的原型新增一个 weight 属性,
第一次新增的时候并没有给它赋值, 因此子对象 child1 查看原型时, 原型没有 weight 属性
第二次新增的时候给属性赋值了, 因此 child1 查看原型的时候, 原型中出现了 weight 属性
(2) 用对象给原型赋值
- 可以通过用
子类构造函数.prototype = {}
给原型赋值
Constructor.prototype = {};
-
备注
这种操作对已经生成的子类对象无效,
因为原型是对象, 是引用值, 因此方法 1 通过构造函数调用的原型和子类对象查看的原型是同一个对象,
所以方法 1 的修改会对已生成的子类对象有效
但这种重新给原型赋值的操作, 会让构造函数先切断对原本的原型的引用,
然后再和新原型之间建立引用, 因此这种方法修改原型后, 只能在修改后用构造函数生成的子对象看到
就会造成同一个构造函数生成的子对象的原型并不相同 -
如下所示
构造函数修改后
child1 的原型并没有发生改变
然后再用构造函数生成新对象 child2
child2 的原型则换成了新的原型
3. 构造器
-
作用
constructor 是可以从原型继承而来的, 原型会自带初始构造器, 这个构造器来自 Object 类.
构造器可以指引对象生成时调用的函数,这个属性解决了对象识别问题,
即可以通过该属性判断出实例是由哪个构造函数创建的. -
如下所示
首先, 生成两个构造函数, 分别为 Test01 和 Test02
然后, 通过 Test01 来创造一个子对象 theone
通过调用可知 theone 的构造器指向了 Test01
接着, 将 Test01 的原型的构造函数的指向改为 Test02
通过调用可知 theone 的构造器的指向变成了 Test02
但是 theone 的内容没有发生改变, 还是原来的属性值
然后, 再通过 Test01 创建一个新的子对象 thesecond
通过输出可知, thesecond 的属性值还是由 Test01 设定的一样
但是通过调用可知, thesecond 的构造器指向变成了 Test02
即, 即使改变了构造器的指向, 决定子对象的属性内容的依旧是被调用的那个构造函数,
构造器的指向只是用来说明这个子对象是由哪个构造器生成, 并不会影响生成的子对象的属性值.