您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

继承JavaScript系列的方法 <源码交易>

  • 时间:2022-10-27 00:32 编辑: 来源: 阅读:301
  • 扫一扫,手机访问
摘要:继承JavaScript系列的方法 <源码交易>
半年没升级文章了。上半年我一直处于焦虑状态,并不是很想动笔。直到现在,我才意识到,一直焦虑不是一个好主意。不如安顿好自己,提升自己,哪怕有一些特殊的个人情况。但我相信金子总会发光,或者不会发光,但至少我努力过~ ~影像今天是中秋国庆假期的最后一天。抓住尾巴,写完一篇文章。继续写上一篇的续篇~这篇文章需要准备一台电脑,一个大脑,一杯咖啡。1.原型链继承了上一篇文章中原型链的概念。其实这也是传承方式之一。因为ECMAScript中没有类的概念,所以有时候我有自己独立的属性或方法,但是有些地方和另一个对象的属性或方法非常相似。比如我们之前创建了一个动物类,然后这个类包含了名字和身高。代码如下:功能动物(姓名、年龄、身高){ this.name = namethis.age =年龄;this.height =高度;} animal . prototype . eat food = function(food){ console . log(` $ { this . name }喜欢吃$ { food } `);} animal . prototype . getweight = function(weight){ console . log(` $ { this . name } weight $ { weight } kg `);}let buouCat =新动物('布偶猫',3,10);buoucat . eat food(');//布偶猫喜欢吃buo ucat . getweight(30);//布偶猫重30公斤然后有一天新的需求来了。需要做鸟类的详细记录吗?他们会飞吗?它们也有名字,多大,多高,喜欢吃什么,体重多少?看这只鸟,它也是动物之一。需要记录的东西,动物类都有,只需要继承就行了。如何实现传承?或者使用prototype让一个对象继承另一个对象的属性和方法。见code://新增代码函数Bird(is fly){ this . is fly = is fly;}Bird.prototype =新动物();bird . prototype . isolate = function(){ console . log(` $ { this . name }是${this.isFly?飞行':'不会飞的鸟' } `);};设b1 =新鸟(真);B1.name = "燕子";B1 . iso rfly();//燕子是飞鸟B1 . eat food(‘虫子’);//燕子喜欢吃虫子。用Bird的原型实例化Animal构造器,然后Bird的原型指向Animal,扩大了原型搜索。首先,将在Bird中搜索该属性。如果找不到,就沿着Bird的原型向上搜索。如果找不到,就退回去。如果找不到,它将继续搜索,直到原型链结束。这是原型链的继承方法。 当然,如果Bird类重写它喜欢吃哪种虫子,它会重写Animal类的eatFood方法。见代码:bird.prototype.eatfood (food1,food 2){ console . log(` $ { this . name }喜欢吃${food1},但一般吃$ { food 2 } `);}b1.eatFood('米','虫');//燕子喜欢吃米饭,但一般会吃虫子。 原型链看起来很强大,但它仍然有弱点。上一篇文章中“原型”的细节是,它仍然影响引用类型方面的所有实例对象,原型链也是如此。看代码://如果添加一个引用类型函数Animal (name)的新属性{ this . name = name this . info = { is sleep:true,iseat: true,} } Animal . prototype . eat food = function(food){ console . log(` $ { this . name }喜欢吃$ { food } `);} animal . prototype . getweight = function(weight){ console . log(` $ { this . name } weight $ { weight } kg `);}函数Bird(){ } Bird . prototype = new Animal();设b1 =新鸟();设b2 =新鸟();//然后我要修改b1的info引用类型B1 . info . is sleep = false;//然后看看b2的信息有没有变?console . log(B2 . info . is sleep);//假的,嗯?不,我只是想改变b1的属性,但结果影响b2。那是因为Animal的所有属性都在Bird的原型上,然后Bird实例化b1和b2对象,它们具有相同的原型属性。改变b1的info相当于改变了prototype的info,然后读取b2的info,是从prototype的info属性(此时已经改变了这个所以,这是prototype链的一个弱点,所以出现了借用构造函数。2.在借用构造函数完成整点的时候,被一个子类型构造函数中的父类型的构造函数调用,所以可以通过调用和应用来执行,所以鸟具备了动物的所有属性,这就是借用构造函数的过程。好处是实例化多个对象时,每个实例对象都是独立的,互不影响。看代码:function animal(name){ this . name = name this . info = { is sleep:true,iseat: true,} } function bird(){ animal . call(this);}设b1 =新鸟();设b2 =新鸟();B1 . info . is sleep = false;B2 . info . is sleep = true;//只是借用构造函数,不能重用父类型的原型对象,很可惜。参见code:function animal(name){ this . name = name this . info = { is sleep:true,iseat: true,} } animal . prototype . say name = function(){ console . log(`此动物的名称为$ { this . name } `);}函数Bird(name){ Animal.call(this,name);}设b1 =新鸟(‘麻雀’);B1 . say name();//错误:VM 3962: 1未计数类型错误:b1.sayName不是函数找不到b1.sayname()。因为call或apply只能执行构造函数,不包含构造函数的prototype对象,所以只有找不到才会报错,所以这就是缺点。这就引出了组合继承的概念,不得不感叹es ~ 3的故事真多。组合继承虽然原型链和借用构造函数都有缺点,但不能因为白板上的一个小黑点就全部否定。他们还是有自己的优势的。原型链的优点是可以继承原型属性和方法,借用构造函数的优点是实例对象可以独立继承构造函数的属性,所以结合这两者的优点。这叫做组合遗传。怎么实现,或者用上面的代码来优化?参见code:function animal(name){ this . name = name this . info = { is sleep:true,iseat: true,} } animal . prototype . say name = function(){ console . log(`此动物的名称为$ { this . name } `);}function Bird(name){ //借用构造函数继承属性Animal.call(this,name);}//新增代码bird . prototype = new Animal();//原型链继承let b1 =新鸟('麻雀');B1 . say name();//这种动物的名字叫麻雀let b2 =新鸟(‘猫头鹰’);B2 . info . is sleep = false;B1 . info . is sleep//true;改变info中的isSleep不影响另一个实例对象的info(感谢构造函数),然后就可以打印sayName方法了(感谢原型链)~所以这是JavaScript中最常用的继承方法,那么是不是最完美的呢?不是,但也有缺点。这个我们以后再说~ 4。原型继承类似于上一篇文章中的原型模式。使用prototype将已知对象分配给未知对象。看代码:function object(o){ function f(){ } f . prototype = o return new f();}let animal = { name:' ',info:{ isSleep: true,isEat:true } } let cat = object(animal);cat . name =“”;cat.name//cat . info . is cute = true;animal.info//{issleep: true,iseat: true,iscute: true}要说优点,如果只要求对象相同,可以考虑用这个,但是引用类型还是个缺点,和原型链一样,慎用~ 5。寄生继承这是对原型继承的改进,创建一个封装继承过程的函数,然后返回对象,用法更像工厂模式,见代码:function object(o){ function f(){ } f . prototype = o return new f();}函数create(obj){ let clone = object(obj);clone . say name = function(){ cobsole . log(this . name);}返回克隆;}let animal = { name:' ',info:{ isSleep: true,isEat:true } } let a1 = create(animal);a1 . say name();//' '缺点是不能重用函数~但优点还是可以借鉴的。为什么是这种说法?继续看~ 6。寄生结合遗传。嗯,寄生+组合遗传,组合遗传有它的缺点如上所述。缺点是什么?我们来看代码:function animal(name){ this . name = name this . info = { is sleep:true,iseat: true,} } animal . prototype . say name = function(){ console . log(`这个动物的名字是$ { this . name } `);}函数Bird(name){ Animal.call(this,name);//第二次调用动物构造函数} bird . prototype = new Animal();//第一次调用动物构造函数let B1 = new Bird(‘麻雀’);B1 . say name();//这种动物的名字叫麻雀let b2 =新鸟(‘猫头鹰’);B2 . info . is sleep = false;B1 . info . is sleep//true;Bird类调用动物构造函数两次。第一次是在Bird原型上调用动物构造函数Bird.prototype=new Animal(),Bird.prototype有名字和info。第二次调用Bird构造函数的时候,动物构造函数Animal.call(this,name),然后b1有name和info,把Bird.prototype上的Name和info屏蔽掉了,看下面的截图:image我们最初的目的是继承父类的prototype对象,并不包括构造函数的所有属性,所以我们需要的只是父类的prototype的一个副本,所以这就需要寄生继承,父类的prototype对象可以看作一个对象。然后赋给原型函数object(o){ function f(){ } f . prototype = o返回新的f();}函数clonePrototype(child,parent){ let pro = object(parent . prototype);//创建新对象pro.constructor = child//不要忘记将construcotr指向子类型,这样instanceof就可以正常使用child.prototype = pro//赋给subtype}函数animal (name)的原型{ this . name = name this . info = { is sleep:true,iseat: true,} } animal . prototype . say name = function(){ console . log(` this animal的名字是$ { this . name } `);}函数Bird(name){ Animal.call(this,name);}clonePrototype(鸟,动物);Bird.prototype =新动物();//第一次调用动物构造函数let B1 = new Bird(‘麻雀’);B1 . say name();//这种动物的名字叫麻雀。那么我们来看看寄生组合继承的打印结果:图像可以发现鸟的原型没有名字和info,可以避免重复,同时保留原型链的特征,所以这是最好的继承方法~好了,咖啡喝完了,就是这样~如有错误,请指出来,笔芯~


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)
【技术支持|常见问题】别告诉我你没看过邰方这两则有思想的创意广告! (2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部