在使用封装方法时,当创建了多个对象,则会开辟多个内存空间,对资源造成了极大的浪费。这个时候原型(prototype)就派上用场了。原型是让多个创建的对象在不创建内存的情况下使用一个构造函数,每个函数都会有默认的prototype对象和proto的属性。
原型对象
创建函数的时候默认会创建一个新的对象叫prototype。
function show(){
}
console.log(show.prototype);
在浏览器中会显示prototype,发现里面有个叫constructor的方法。
这样,constructor和prototype就开始了无线套娃模式,prototype里面存在constructor,constructor这表明prototype是由哪个对象创建的。
当对象里面的prototype被赋值时,constructor就会被取代掉
show.prototype={
name:'demo',
}
除非重新定义constructor函数,否则在原型对象里面不会出现默认构造函数,当然,如果用“.”来操作的话只是添加属性,并不会让constructor消失
对象原型
对象原型的作用有点像this指针,当实例化一个对象之后,会存在一个名叫proto的默认指针指向该该函数的prototype
console.log(demo.__proto__===show.prototype);
三者关系
构造函数、对象原型和原型对象这三者就形成了一种美妙的铁三角关系。构造函数和原型对象之间相互套娃,彼此指向对方。实例化后的对象里面的对象原型则又指向构造函数里面的原型对象,所以可以说实例化对象其实就是通过构造函数的protorype来进行实例化的
原型链
在这三者的关系延伸上发现原型对象里面也有一个原型指针指向一个名叫Object的原型对象,进一步研究发现这个Object里面的constructor指向了这个Object的构造函数,Object的原型对象呢里面又有一个__proto__指针指向了null.
那么这个null就是这整个链路的最底层了
在检索优先级上面,对象实例上的属性会优先检索到,其次是主原型对象,再是Object,后面就返回空了.
function show(){
this.name=name
}
show.prototype.name='lbzz2'
let demo=new show()
demo.name='lbzz1'
console.log(demo.name);
输出结果为lbzz1,所以对象属性优先级高于原型对象属性,后面的如法炮制