每一个函数都有一个属性,这个属性名就叫做prototype
prototype的属性值是一个对象
原型它就是函数的一个prototype属性
这个函数的prototype属性里面有什么,它可以干什么
默认的prototype对象里面有一个constructor属性,这个constructor属性的值是原本的这个函数
也就是通常所说的constructor指向构造函数本身
prototype能干什么呢?
可以给prototype对象里面添加一些对象的属性和方法,也就是常说的将方法和属性挂载在原型上面,这样我们的实例对象就可以使用原型上的属性和方法了
//有一个函数Child
function Child(){
}
const c = new Child();
Child.prototype.name='ff'
console.log('结果:',c.name); //结果:ff
对Child函数进行实例化,那么这个函数就变成了一个构造函数,那构造函数它也是函数
也就是说它也有prototype属性,那么在prototype上添加一个属性name用实例对象访问这个name,它的值打印出来的就是添加的这个值
?
可以将其看成是一个链条,链条的每一节都有一个连接点,那么原型链的连接点是一个叫proto的东西,这个proto是一个实例对象的一个属性,通过proto可以指向构造函数的prototype属性,可以叫它隐式原型,因为这两个是相等
console.log(c.__proto__==Child.prototype) //打印的是:true
所以实际上实例的proto属性和构造函数的prototype属性指向的是同一块内存
那原型链有什么作用呢?
要知道查找一个对象属性,它的一个顺序是怎么样的
比如这里有两段代码parent和child
<script>
Object.prototype.name="最高级"
function Parent(){
this.name='年轻就是好啊'
}
Parent.prototype.name='前端'
function Child(){
this.name=='child'
}
Child.prototype={
name:'child prototype',
__proto__:new Parent()
}
const c=new Child();
console.log(c.name)
</script>
参照上方代码原型链说明:
parent和child里面分别自身上面有个name属性,那它自身的一个prototype属性上,也有一个name属性,然后我们再对这个child进行一个实例化
对象属性的查找顺序是:首先在自身上面去查找,那如果说有的话,就打印出来,如果自身上面没有就会打印出原型上面的name属性,也就是child prototype,那如果说原型属性上面,还没有这个name,那么它就顺着这个proto向上查找,向上找到parent,那parent里面同样先在构造函数里面找,找到了构造函数里面的name属性,就打印出了年轻就是好啊这几个字,那如果构造函数里面没有,继续在parent原型上面找,找到了前端,那如果这里还没有的话,那么继续顺着proto往上找找到最顶层的一个object,它的Object prototype里面有一个name,那么就打印出这个最高级,那如果还没有的话,输出的就是一个undefined,这样的查找顺序就形成了一条链,也就是我们常说的原型链,那按照原型链查找属性的这样一个特性,我们可以实现一个继承