【js大师之路】详解从示意图继承到组合继承从原型链的生成
基于javascript原型链的渐进式搜索规则和原型对象的共享特性,实现继承非常简单
1.将父类的实例对象分配给子类的原型对象可以实现继承
函数Person(){ this . username=' ghost Wu ';} person . prototype . show username=function(){ return this . username;}函数教师(){}教师. prototype=new Person();var oT=新教师();console . log(ot . username);//ghost Wu console . log(ot . show username());//ghostwu可以通过将父类(Person)的一个实例赋给子类Teacher的原型对象来继承,子类的实例可以访问父类的属性和方法
如果你画不出这幅画,你需要读我的文章:
[js大师之路]一步步来说明javascript的原型对象和原型链
在第11行,执行oT.userName首先,在oT对象上查找它。很明显,ot对象上没有属性,所以沿着oT的隐式prototype _ _ prototype _ _的方向查找teacher.proTotype。
我发现仍然没有userName属性。我继续搜索Teacher.prototype. _ _ proto _ _,发现这个新Person()的实例上有一个userName,值是ghostwu
所以停止搜索,输出幽灵。
在第12行,执行oT.showUserName之前的过程与上面相同,但是在new Person()的实例上仍然找不到showUserName方法,因此继续遵循new Person()的示例
隐式原型__proto__ (Person.prototype)搜索,找到方法showUserName on Person.prototype,停止搜索,输出ghostwu。
其次,将父类的原型对象分配给子类的原型对象可以继承父类的方法,但不能继承父类的属性
函数Person(){ this . username=' ghost Wu ';} person . prototype . show username=function(){ return ' person :3360 show username method ';}函数Teacher(){ } Teacher . prototype=person . prototype;var oT=新教师();console . log(ot . show username());//ghost Wu console . log(ot . username);//未定义,没有从父类继承的用户名。由于teacher . prototype(_ prototype _ _)的隐式原型只指向Person.prototype,因此无法获取Person实例的属性。
第三,继承关系发生后,判断实例和构造函数(类)的关系
或者通过实例来判断
函数Person(){ this . username=' ghost Wu ';} person . prototype . show username=function(){ return this . username;}函数教师(){}教师. prototype=new Person();var oT=新教师();console.log(教师的oT实例);//true console . log(Ot instance of Person);//true console.log(对象的oT实例);//true console . log(teacher . prototype . isprototypeof(oT));//true console . log(person . prototype . isprototypeof(oT));//true console . log(object . prototype . isprototypeof(oT));//true 4。子类可以覆盖(重写)父类中存在的方法和属性,子类中不存在的方法和属性可以扩展
function Person(){ } Person . prototype . show username=function(){ console . log(' Person :3360 show username ');}函数教师(){ }教师. prototype=new Person();teacher . prototype . show username=function(){ console . log(' teacher :3360 show username ');} teacher . prototype . show age=function(){ console . log(22);} var oT=new Teacher();ot . show username();//教师: show username . ot . show age();//22 V .重写原型对象后,实际上改变了原型对象__proto__的方向
原型对象的__proto__点发生了变化,将覆盖(切断)原来的继承关系
function Person(){ } Person . prototype . show username=function(){ console . log(' Person :3360 show username ');}函数教师(){}教师. prototype=new Person();teacher . prototype={ show age : function(){ console . log(22);} } var oT=new Teacher();ot . show age();//22 ot . show username();在上面的示例中,在第7行中,教师原型覆盖了教师的原型对象,因此第6行中原型对象的隐式原型(_ prototype _)指向没有影响
因此,在第14行,oT.showUserName()会被错误调用,因为老师原型对象的隐式原型(_ _ prototype _ _)不再指向父类(Person)的实例,继承关系被打破。
第六,在继承过程中,在实例的属性上小心处理引用类型的数据
function Person(){ this . skills=[' PHP ',' JavaScript '];}函数教师(){}教师. prototype=new Person();var oT1=新教师();var oT2=新教师();ot1 . skills . push(' Linux ');console . log(OT2 . skills);PHP、Java、linux的技巧OT 1增加了一个Linux数据,其他实例可以访问,因为其他实例共享技巧数据,技巧是引用类型
七、借用建造师
为了消除引用类型对不同实例的影响,可以借用构造函数将引用类型的数据复制到每个对象中,这样就不会相互影响
函数Person(uName){ this . skills=[' PHP ',' JavaScript '];this.userName=uName} person . prototype . show username=function(){ return this . username;}函数教师(uName ){ Person.call(this,uName);} var oT1=新教师();ot1 . skills . push(' Linux ');var oT2=新教师();console . log(OT2 . skills);//php,JavaScript console . log(ot2 . show username());虽然oT1.skills增加了一个Linux,但是它的调用并不影响oT2.skills的数据,通过调用子类的构造函数,借用父类的构造函数,复制父类的属性,还
传递参数,例如第8行,但是第15行,方法调用是错误的,因为在构造中只复制属性,而不是父类的原型对象上的方法
八、组合继承(原型对象借用构造函数)
经过以上分析,单一原型继承的缺点是:
1.不能传递参数,例如,
teacher . prototype=new Person();有人说括号后面可以跟参数,没错,但是只要后面跟参数,子类的所有实例属性都是这样的。说白了,他们还是传不了参数
2.将引用类型放在原型对象上会对不同的实例产生相互影响
单一借用构造函数的缺点;
1.无法复制到父类的方法
只是原型对象的缺点可以用构造函数来弥补,原型对象的缺点可以用构造函数来弥补。因此,产生了一种组合遗传方法:
函数Person(uName){ this . skills=[' PHP ',' JavaScript '];this.userName=uName} person . prototype . show username=function(){ return this . username;}函数教师(uName ){ Person.call(this,uName);} teacher . prototype=new Person();var oT1=新教师(' ghost Wu ');ot1 . skills . push(' Linux ');var oT2=新教师(' ghost Wu ');console . log(OT2 . skills);//php,JavaScript console . log(ot2 . show username());//ghostwu子类实例oT2的技能不会受到oT1的影响,子类实例也可以调用父类的方法。
以上【js大师之路】详细讲解了从图式继承到组合继承从原型链的生成,这是边肖分享的全部内容。希望能给大家一个参考,支持我们。
版权声明:【js大师之路】详解从示意图继承到组合继承从原型链的生成是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。