分析问题套路:是什么,用来做啥,
原型
什么是原型? 为了了解这个概念,我们需要先由一个构造函数入手。
创建一个构造函数:
function Father(){
}
prototype
然后我们引入一个新的概念----prototype。
什么是prototype?
简单来说就是prototype是每个函数都有的,创建时为空的一个属性。相当于对其他对象的引用。这里指向的其他对象是什么呢?
他和原型有啥关系吗?
实际上,prototype指向的对象就是我们通过构造函数创建的对象的原型。
我们将这个指向的对象(原型)叫做"xxx.prototype"
可以这么表示
用来做啥?
通过上面的构造函数创建俩对象:
var father1 = new Father();
var father2 = new Father();
\
然后我们让他俩的原型多一个属性name:
Father.prototype.name = "daming";
多之前:
多之后再访问一下他俩的name属性,此时发现
这俩父亲的name都是原型里我们让多出来的。
由此我们可以发现,访问对象的属性时,若对象里没有,则会从对象的原型里找。
prototype是对于函数而言的,那么对于对象而言用啥来表示原型呢?
proto
这是每一个javascript对象都有的一个属性,proto,这个属性会指向对象的原型。
和前面构造函数创建的对象的原型(xxx.prototype)是同一个东西。
所以又有
\
实例对象和构造函数都可以指向原型,那原型可以指向啥?
constructor
这就是原型指向要用的东西----constructor。
我们调用一下看看:
噢,它指向了构造函数。
至于实例对象,好吧跟他没啥关系了。
原型链
原型讲得差不多了,那么原型链又是啥。
既然叫链,自然是一条连起来的关系带。
于是我们继续了解,原型有没有原型?
既然原型也是一个对象,那么让我们来康康它的_proto_:
它指向了一个-----对象?这个对象可以理解为原始对象的prototype。自然他也是通过构造函数Object()创建出来的一个实例对象。它的constructor也指向构造函数Object()。
我们把这个对象叫作Object.prototype,那他有没有原型呢?
康康:
null,说明,再往上就没了。
由此形成的一条关系带就可以理解为:原型链。
即关系图中的蓝线。
当访问一个实例对象的属性时,若对象里没有,则会从对象的原型链里依次向上查找,继承属性。
这里的继承并不意味着复制操作,而是通过委托访问。
引用《你不知道的JavaScript》中的话,就是:
继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。
参考
- JavaScript深入之从原型到原型链 冴羽
- 《你不知道的javascript》
- 《javascript高级程序设计》