实现js面向对象继承

原创 心理学徒幽灵聪 随笔 小白 224阅读 2017-11-15 11:35:12 举报

一年一度的双十一又过去了,面对朋友圈的疯狂狗粮,作为一名程序员,内心毫无波动,嗯,毫无波动,默默提醒自己,万物皆对象

实现js面向对象继承

众所周知,编程思想有两种,面向过程和面向对象,而面向对象有三大特征,封装,继承和多态,今天,简单跟大家聊聊如何实现js中的面向对象继承,抛砖引玉,欢迎各位道友参观指正

首先构建一个基类Person,设置属性name和age,同时在原型中添加一个方法say
想让子类继承父类,第一想到的就是利用apply方法,将父类的属性和方法复制过来,ctrl+c + ctrl+v 手动滑稽~

html 代码

实现js面向对象继承

在上述代码中,利用apply方法,将基类的方法调用到子类,可以看到,对属性的设置已经生效,name和age已经可以打印出来,但是调用方法,却提示undefined,这是因为
当JS的一个object的属性或者方法被访问的时候,JS会先在自己身上寻找这个属性或者方法。如果自身没有,则去自己的原型(注意,这个原型不是自己的prototype那个属性)寻找,如果自己的原型寻找不到,则再去自己原型的原型寻找,依次类推,这个过程也就是所谓的prototype-chain.

可以看到,实例化生成的new_chinese的原型链为 new_chinese->Chinese->Object,而在 new_chinese中没有该方法,向上找原型,Chinese和Object中都没有这个方法,所以报错了


既然new_chinese的原型链中没有say这个方法,那么我们在Chinese中添加这个方法,就可以解决这个问题,
第一想到的就是Chinese中的prototype没有方法,那直接把Person的prototype拷贝一份过来,这样就可以使用方法了,嗯,说干就干

html 代码

实现js面向对象继承

可以在上图看到,虽然可以使用say方法 了,但是!!被拐跑了有木有,new_chinese的构造函数直接指向了Person而不是Chinese,

这是因为prototype是一个对象,是引用类型, prototype和constructor是两个不可枚举属性,所以,在函数的prototype中有constructor,而constructor又指向该函数本身,而在Chinese.prototype = Person.prototype;的过程中,将Chinese中的指针prototype指向了Person中的prototype,而Person中的prototype的constructor则是指向 了Person,所以会出现这样的错误


为了解决这种问题,第一反应,嗯,O_O,又是第一反应。。。。
嗯,
我有一个大胆的想法

将Person.prototype.constructor再指向Chinese?

实现js面向对象继承

这样做Chinese中的指向正常,但是会导致Person自身constructor指向错误,囧


所以需要一个中间值来接收Chinese.prototype的指向,而且可以使其constroctor指向回Chinese,而且不会影响Person中的prototype和constructor的指向
so~利用实例化的Person作为中间值

所以第三版~

html 代码

实现js面向对象继承

这样,就可以正确调用父类的方法,并且可以体现正确的原型链 new_chinese->Chinese->Person->Object;

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复