话不多说,直接上MDN链接
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
说实话啦,上面讲的非常非常详细,大家可以移步去看原文哦,我这里分享一下自己的理解 。
啥是继承
我们知道在js中,万物皆对象,而每一个实例对象(object)都有自己的私有属性(proto)指向它的构造函数的原型对象(prototype),而这个原型对象也有自己的自己的原型对象(proto),层层向上知道一个对象的原型对象为null。根据定义,null没有原型,并作为这个原型链的最后一个环节。简单来说,我继承我爸爸的财富,我爸爸继承我爷爷的财富,我爷爷继承我曾爷爷的财富…直到我的祖先,这个关系链就叫原型链,财富的延续就是继承 。
基于原型链的继承
MDN的官方解释(JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。)
look!是不是非常的浅显易懂,我们来个小example!
我们从函数里创造了一个对象实例o,o自然是继承它老爸的属性的(a和b),所以,我们输出o.a和o.b的时候,其实就是o本身属性a和b,输出的是1和2,尽管我们把老爸b的值更为为3,但输出的b的值仍为2。这里我们要清楚一个逻辑,我们判断其一个属性是否是它的,我们首先要看它有没有,如果他有,我们就认定是它的,如果他没有,我们再顺藤摸瓜,往上找它的原型对象。所以这里o.b是o有的,我们就输出2(这就是属性遮蔽)。同理输出o.c也是如此,c并不是o的自身属性,所以我们要看它的原型对象有没有,c是o.[[Prototype]]的属性吗?是的,该属性的值为 4,我们输出4。所以最后o.d的输出也就是undefined啦。附上一张输出图
继承方法
js中并没有所谓的方法,在js中,任何函数都可以被添加到对象中并作为该对象的一种属性,上述的属性遮蔽也同样适用于函数(也就是所谓的方法重写)。
最后放一张图