JavaScript |构造函数和原型 + 继承 + 类的本质 + ES5 中的新增方法 + 构造函数原型 prototype + 对象原型 proto + constructor构造函数
什么是原型?
- 原型是一个对象,我们称
prototype
为原型对象。
JavaScript 规定,每一个构造函数都有一个 prototype
属性,指向另一个对象。注意这个 prototype
就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
我们可以把那些不变的方法,直接定义在prototype
对象上,这样所有对象的实例就可以共享这些方法。
原型的作用是什么 ?
- 共享方法,不必再开辟内存空间,所有的实例都可以使用这个方法,节约了内存资源
对象原型
对象都会有一个属性__proto__
指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__
原型的存在。
constructor 构造函数
对象原型( __proto__
)和构造函数(prototype)原型对象里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身。
prototype:每个函数都有一个prototype属性,这个属性指向函数的原型对象。
__proto__
:这是每个对象(除null外)都会有的属性,叫做__proto__
,这个属性会指向该对象的原型。constructor:每个原型都有一个constructor属性,指向该关联的构造函数。
构造函数、原型和实例的关系:
每个构造函数都有一个原型对象(
.prototype
),原型对象都包含一个指向构造函数的指针(.constructor
),而实例都包含一个指向原型对象的内部指针(.__proto__
)。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?
显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。
简单的表达就是:
- 如果实例没有一个属性,它会去它的原型
prototype
中去找,但是如果它的原型中也没有这个属性呢,会停止寻找么,不一定,因为它的原型可能也有自己的原型,这个时候他就会去它的原型的原型中去寻找,这个时候会停下么,还是不一定,要看他原型的原型有没有原型,这样就形成了一条原型链。- 直到最后一个找不到原型时返回null