一.名词解释
构造函数:构造函数是一个具有属性和方法的函数,名称首字母一般要大写,他可以实例化一个对象,这个对象可以继承他的属性和方法。设这里设函数名为Example()
原型对象:原型对象是一个对象,它指向一个构造函数,用Example().prototype表示
实例对象:实例对象也与构造函数有关,实例对象是构造函数创建的一个对象, 通过
example = new Example()创建
原型:原型是实例对象具有的属性,由example.__proto__表示,指向的是创建该实例对象的原型对象。
二、关系
一、原型:
1.其中,Person是一个构造函数,a是调用Person这个函数的一个实例对象,那什么是原型呢?
每个函数都有一个prototype属性,而这个属性则会指向调用其的实例对象的原型,也就是说,Person.prototype就是a的原型。
2.函数通过prototype属性指向调用其的实例对象的原型,那么,该实例对象又如何指向他自己的原型呢?
每个对象也都有一个__proto__属性,该属性指向其原型,也就是:
a.__proto__ === Person.prototype // true
也就是说:a.__proro__和 Person.prototype 都是 a 的原型。
3.为何会有原型这个东西呢?原型有什么用呢?
我个人的理解:
在上图中,每创建一个实例对象 a 的时候,就会调用一次 alertName方法,这样就不太好,所以我们就有了原型 ,我们把这个方法放在原型中:
Person.prototype.alertName = function(){
console.log(this.name)
}
这样,我们在创建一个实例对象的时候就不会调用 alertName 方法了。
4.为何将方法放在原型里,在创建实例对象的时候就不会调用 alertName 这个方法了呢?
因为在实例对象使用其属性的时候,最先是看自身有没有这个属性,若自身没有这个属性,则会查找其原型有没有这个属性,若其原型有这个属性,那么其自身也就有这个属性了,若其原型也没有这个属性,那么则查找其原型的原型有没有这个属性,若有,则其就可以用这个属性了,以此类推,若直到最高的这个原型都没有这个属性的话,就会返回undefined。也就是说,一个原型可以对应很多个实例对象,而那些实例对象有一个共同的原型,可以公用他们的原型的属性。
5.原型的原型是什么呢?
原型也是一个对象,所有原型的原型也是一个对象,我们可以和创建一个实例对象那样来创建一个原型:
其实原型对象就是由Object构造函数创建的一个实例对象
6.哪个是最高的那个原型呢?
以上面的例子为例:a ---> Person.prototype(a.__proto__) ---> Object.
其中Object是最高的原型,在javaScript中,所有对象最终的原型就是Object,而Object则没有原型。
二、原型链:
我们可以知道,a 这个实例对象可以通过 __proto__ 这个属性指向其原型对象,而其原型对象也可以通过 __proto__ 这个属性指向其原型对象,而这,也就形成了一条链,这个就是原型链。
三、补充:
实例对象可以通过 __proto__ 属性联系到其原型对象,那么其原型对象又如何联系到他自身呢?
答案就是:原型对象可以通过constructor这个属性指向创建这个对象时调用的那个对象(构造函数也是对象类型)