JavaScript 原型与原型链
1.什么是原型?
一个对象当他被生成的时候,就会自带一个属性 __ Proto __ ,我们将其称为 隐式原型
一个(通常为构造函数)函数对象被生成的时候,会有一个ProtoType 属性,我们将其成为 显式原型
我们通常会利用构造函数创建实例对象
function Fn(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
var fn =new Fn("xiaoming","18","male");
fn是我们的实例对象,Fn则是构造函数。
在执行构造函数的时候,JS会自动执行
fn.__proto__ = Fn.prototype;
即将构造函数的显式原型属性,赋值给实例对象的隐式原型属性
如图:
这样做的意义是什么呢?
一句话:让实例对象fn能够使用Fn原型对象中定义的一些方法和属性
举个例子:我们在Fn的原型对象中添加了一个方法f1();
从结果看,fn实例对象,能够使用Fn原型对象的中所定义的方法。
为什么?
2.原型链
这里就涉及到了原型链的概念
其中利用__ proto __去寻找原型的过程,就称为原型链,更准确的说是隐式原型链(沿着隐式原型寻找)
3.原型链继承
我们都知道JavaScript中存在继承,所有的对象,都是继承于Object对象,那么理论上是我们利用原型链是可以使用Object中所定义的方法
理解的关键点在于:Fn原型对象本质也是一个由Object构造函数所产生的Object实例
我们利用原型链,就可一步步访问到Object原型对象中所定义的方法 :toString()等
补充一点:Object原型对象的__ Proto __ 指向原型链的终点
4.深入理解原型链
我们知道构造函数对象也是一个对象,是对象,那么自然就拥有对应的构造函数和原型对象
即:构造函数的构造函数
上图的结果是显然的。
但是对于Function对象,有一个特殊的地方,他作为所有函数对象的构造函数,他的_ proto _ 属性又是什么呢?
我们知道 一个对象的 _ proto __ 属性是他所对应的构造函数的 protoType 属性,但是 Function这个函数的对象的构造函数的构造函数又是什么呢?
Function的构造函数就是Function本身
因此Function对象的proto属性指向Function的原型对象
那么我们继续完善这张图:
- 首先Object构造函数的__ proto __ 是什么呢?
Object 构造函数是由Function对象,这个所有函数的构造函数所产生,那么其 __ Proto __ 属性,就等于Function对象的ProtoType属性
- 第二个问题 Function 原型对象的 __ Proto __ 又是什么呢?
首先他本质是一个Object对象,那么他的__ proto __ 就指向 Object 原型对象,原理和Fn原型对象相同
- 最后我们来理解以下,Constructor 属性
每一个原型对象,由有一个Constructor属性,他的值指向所对应的构造函数