以下认识都属于个人观点:
首先先了解原型对象和原型的概念:
原型对象:
原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。所有的原型对象都是由Object构造函数创建出来的。
原型:
原型是一个对象,是函数的一个属性prototype;通过该函数实例化出来的对象都可以继承得到原型上的所有属性和方法。
构造函数:
通过new 函数名来实例化对象的函数叫构造函数。任何的函数都可以作为构造函数存在。
系统提供的构造函数:Function、Object等。
原型链:
每一个对象都从原型继承属性,直到null结束。
在JavaScript中万物都是对象,而对象和对象之间并不是独立存在的,对象和对象之间都有一定联系,而他们通过一种链式结构联系在一起,而这种链式结构就是原型链。
首先,一张通俗易懂的原型链图能够了解其中的结构:
注:所有的构造函数都是对象,故称为函数对象。
Function函数对象是自动生成的第一个对象
除了Function函数对象以外,所有的函数对象都是由Function函数对象创建的。
Function会自动创建出很多的函数对象出来,包括Object函数对象。而Object函数对象是Function自动创建的第一个函数对象。
所有的函数对象中都有一个叫做prototype的引用类型变量,而这个引用类型变量的值是对应原型对象的引用值,即该函数对象中的prototype指向它的原型对象。
同理,所有的原型对象中都有一个叫做constructor的引用类型变量,而这个引用类型变量的值是对应函数对象的引用值,即该原型对象中的prototype指向它的函数对象。
所有的对象中都有一个名为__proto__的引用类型变量,该引用类型便是对象的成员。关于__proto__的指向,分为以下几种情况:
1.所有的函数对象的__proto__都指向Function原型对象;
2.除Object原型对象外的所有原型对象中的__proto__都指向Object原型对象;
3.Object原型对象中的__proto__指向null;
4.所有实例对象中的__proto__都指向创建他的函数对象的原型对象。
对象访问成员的过程:
(1)当前对象中如果有该成员就获取该成员,访问结束。
(2)如果当前对象中没有该成员,就通过对应的__proto__指向的下一个对象中去寻找成员,如果找到了就结束,如果没有找到,就继续通过对应的__proto__指向的对象中去寻找,如果最终都没有找到的话,就返回null。
如上图中从实例对象中开始寻找:实例对象p1.__proto__ ==>原型对象Person.__proto__ ==>原型对象Object.__proto__ ==>null
如何分辨函数对象和原型对象:
一个对象中如果有prototype属性,那么该对象就一定是函数对象(构造函数),如果对象为函数对象,那么其中一定有prototype属性;
一个对象中如果有constructor属性,那么该对象就一定是原型对象,如果对象为原型对象,那么其中一定有constructor属性。