品牌 资讯 搭配 材料 时尚 热点 行业 首饰 玉石 行情

深入浅出JavaScript之原型链和继承 环球即时看

2023-05-07 17:10:31 来源:清一色财经

Javascript语言的继承机制,它没有”子类”和”父类”的概念,也没有”类”(class)和”实例”(instance)的区分,全靠一种很奇特的”原型链”(prototype chain)模式,来实现继承。

Javascript语言的继承机制,它没有”子类”和”父类”的概念,也没有”类”(class)和”实例”(instance)的区分,全靠一种很奇特的”原型链”(prototype chain)模式,来实现继承。


【资料图】

这部分知识也是JavaScript里的核心重点之一,同时也是一个难点。我把学习笔记整理了一下,方便大家学习,同时自己也加深印象。这部分代码的细节很多,需要反复推敲。那我们就开始吧。

小试身手

原型链例子(要点写在注释里,可以把代码复制到浏览器里测试,下同)

functionfoo(){}//通过functionfoo(){}定义一个函数对象foo.prototype.z=3;//函数默认带个prototype对象属性(typeoffoo.prototype;//"object")varobj=newfoo();//我们通过newfoo()构造器的方式构造了一个新的对象obj.y=2;//通过赋值添加两个属性给objobj.x=1;//通过这种方式构造对象,对象的原型会指向构造函数的prototype属性,也就是foo.prototypeobj.x;//1//当访问obj.x时,发现obj上有x属性,所以返回1obj.y;//2//当访问obj.y时,发现obj上有y属性,所以返回2obj.z;//3//当访问obj.z时,发现obj上没有z属性,那怎么办呢?它不会停止查找,它会查找它的原型,也就是foo.prototype,这时找到z了,所以返回3//我们用字面量创建的对象或者函数的默认prototype对象,实际上它也是有原型的,它的原型指向Object.prototype,然后Object.prototype也是有原型的,它的原型指向null。//那这里的Object.prototype有什么作用呢?typeofobj.toString;//‘function"//我们发现typeofobj.toString是一个函数,但是不管在对象上还是对象的原型上都没有toString方法,因为在它原型链的末端null之前都有个Object.prototype方法,//而toString正是Object.prototype上面的方法。这也解释了为什么JS基本上所有对象都有toString方法"z"inobj;//true//obj.z是从foo.prototype继承而来的,所以"z"inobj返回了trueobj.hasOwnProperty("z");//false//但是obj.hasOwnProperty("z")返回了false,表示z不是obj直接对象上的,而是对象的原型链上面的属性。(hsaOwnProperty也是Object.prototype上的方法)

刚才我们访问x,y和z,分别通过原型链去查找,我们可以知道:当我们访问对象的某属性时,而该对象上没有相应属性时,那么它会通过原型链向上查找,一直找到null还没有话,就会返回undefined。

基于原型的继承

functionFoo(){this.y=2;}Foo.prototype.x=1;varobj3=newFoo();//①当使用new去调用的时候,函数会作为构造器去调用②this会指向一个对象(这里是obj3),而这个对象的原型会指向构造器的prototype属性(这里是Foo.prototype)obj3.y;//2obj3.x;//1//可以看到y是对象上的,x是原型链上的原型(也就是Foo.prototype上)

prototype属性与原型

我们再来看看Foo.prototype是什么样的结构,当我们用函数声明去创建一个空函数的时候,那么这个函数就有个prototype属性,并且它默认有两个属性,constructor和__proto__,

constructor属性会指向它本身Foo,__proto__是在chrome中暴露的(不是一个标准属性,知道就行),那么Foo.prototype的原型会指向Object.prototype。因此Object.prototype上

的一些方法toString,valueOf才会被每个一般的对象所使用。

functionFoo(){}typeofFoo.prototype;//"object"Foo.prototype.x=1;varobj3=newFoo();

总结一下:我们这里有个Foo函数,这个函数有个prototype的对象属性,它的作用就是当使用new Foo()去构造实例的时候,这个构造器的prototype属性会用作new出来的这些对象的原型。

所以我们要搞清楚,prototype和原型是两回事,prototype是函数对象上的预设属性,原型通常是构造器上的prototype属性。

实现一个class继承另外一个class

functionPerson(name,age){this.name=name;//直接调用的话,this指向全局对象(this知识点整理)this.age=age;//使用new调用Peoson的话,this会指向原型为Person.prototype的空对象,通过this.name给空对象赋值,***this作为return值}Person.prototype.hi=function(){//通过Person.prototype.hi创建所有Person实例共享的方法,(可以参考上节的左图:对象的原型会指向构造器的prototype属性,所以想让obj1,obj2,obj3共享一些方法的话,只需在原型对象上一次性地添加属性和方法就可以了);console.log("Hi,mynameis"+this.name+",Iam"+this.age+"yearsoldnow.")//这里的this是全局对象};Person.prototype.LEGS_NUM=2;//再设置一些对Person类的所有实例共享的数据Person.prototype.ARMS_NUM=2;Person.prototype.walk=function(){console.log(this.name+"iswalking...");};functionStudent(name,age,className){//每个学生都属于人Person.call(this,name,age);//在Student这个子类里面先调用一下父类this.className=className;}//下一步就是我们怎么去把Student的实例继承Person.prototype的一些方法Student.prototype=Object.create(Person.prototype);//Object.create():创建一个空对象,并且这个对象的原型指向它的参数//这样子我们可以在访问Student.prototype的时候可以向上查找到Person.prototype,又可以在不影响Person的情况下,创建自己的方法Student.prototype.constructor=Student;//保持一致性,不设置的话constructor会指向PersonStudent.prototype.hi=function(){//通过Student.prototype.hi这样子的赋值可以覆盖我们基类Person.prototype.hiconsole.log("Hi,mynameis"+this.name+",Iam"+this.age+"yearsoldnow,andfrom"+this.className+".");}Student.prototype.learn=function(subject){//同时,我们又有自己的learn方法console.log(this.name+"islearning"+subject+"at"+this.className+".");};//testvaryun=newStudent("Yunyun",22,"Class3,Grade2");yun.hi();//Hi,mynameisYunyun,I"m22yearsoldnow,andfromClass3,Grade2.console.log(yun.ARMS_NUM);//2//我们本身对象是没有的,对象的原型也就是Student.prototype也没有,但是我们用了继承,继续向上查找,找到了Person.prototype.ARMS_NUM,所以返回2yun.walk();//Yunyuniswalking...yun.learn("math");//YunyunislearningmathatClass3,Grade2.

结合图我们来倒过来分析一下上面代码:我们先通过new Student创建了一个Student的实例yun,yun的原型指向构造器的prototype属性(这里就是Student.prototype), Student.prototype上有hi方法和learn方法,Student.prototype是通过Object.create(Person.prototype)构造的,所以这里的Student.prototype是空对象,并且这个对象的原型指向Person.prototype,接着我们在Person.prototype上也设置了LEGS_NUM,ARMS_NUM属性以及hi,walk方法。然后我们直接定义了一个Person函数,Person.prototype就是一个预置的对象,它本身也会有它的原型,它的原型就是Object.prototype,也正是因为这样,我们随便一个对象才会有hasOwnProperty,valueOf,toString这样些公共的函数,这些函数都是从Object.prototype上来的。这样子就实现了基于原型链的继承。 那我们调用hi,walk,learn方法的时候发生了什么呢?比如我们调用hi方法的时候,我们首先看这个对象yun上有没有hi方法,但是在这个实例中没有所以会向上查找,查找到yun的原型也就是Student.protoype上有这hi方法,所以最终调用的是Student.prototype.hi,调用其他方法也是类似的。

改变prototype

我们知道JavaScript中的prototype原型不像Java中的class,Java中的class一旦写好就很难动态的去改变了,但是JavaScript中的原型实际上也是普通的对象,那就意味着在程序运行的阶段,我们也可以动态的给prototype添加或删除些属性。

在上述代码的基础上,我们已经有yun这个实例了,我们接着来进行实验:

tudent.prototype.x=101;//通过Student.prototype.x把yun的原型动态地添加一个属性xyun.x;//101//那我们发现所有的实例都会受到影响//接着我们做个有趣的实验Student.prototype={y:2};//我们直接修改构造器的prototype属性,把它赋值为一个新的对象yun.y;//undefinedyun.x;//101//所以我们得出:当我们修改Student.prototype值的时候,并不能修改已经实例化的对象varTom=newStudent("Tom",3,"ClassLOLKengB");Tom.x;//undefined//但当我们创建一个新的实例时,这一次x就不见了,Tom.y;//2//并且y是新的值

所以说当动态修改prototype的时候,是会影响所有已创建或新创建的实例的,但是修改整个prototype赋值为新的对象的话,对已创建的实例是不会影响的,但是会影响后续的实例。

实现继承的方式

实现继承有多种方式,下面我们还是以Person和Student来分析

functionPerson(){}functionStudent(){}Student.prototype=Person.prototype;//我们可不可用这种方式呢?这种方法是错误的:因为子类Student有自己的一些方法//,如果通过这样子赋值,改变Student的同时也改变了Person。Student.prototype=newPerson();//这种方式是可以实现的,但是调用构造函数有时候也是有问题的,比如要传进Person一个name和age//,这里的Student是个类,还没实例化,这时候有些奇怪了,传什么都不是。Student.prototype=Object.create(Person.prototype);//相对来说这中方式是比较理想的,这里我们创建了一个空的对象//,并且对象的原型指向Person.prototype,这样我们既保证了继承了Person.prototype上的方法,并且Student.prototype又有自己空的对象。//但是Object.create是ES5以后才有的 

标签:

相关文章

深入浅出JavaScript之原型链和继承 环球即时看

​Javascript语言的继承机制,它没有”子类”和”父类”的概念,也没有”类”(class)和”实例”(instance

2023-05-07 17:10:31

请了代理人,自己可以不出庭吗

​古希腊有一句谚语:“法律不保护躺在权利上睡觉的人。”即法律不保护那些自己拥有权利却疏于维护和管理的人

2023-05-07 16:36:59

为配合京雄高速上跨工程,地铁房山线今日将提前结束运营

​ 新京报讯(记者裴剑飞)记者从北京市交通委获悉,为配合京雄高速公路(北京段)上跨房山线长阳站至篱笆房

2023-05-07 15:53:34

两个马读什么三个马读什么_两个马念什么三个马念什么

​1、马奔跑:biāo解释:众马奔腾的样子。2、2 两匹马并着跑发出的声音骉拼音:1:dú解释騳拼音。本文就为

2023-05-07 15:00:09

以智能机器人为产业导向,上海张江打造国家级机器人产业基地|世界实时

​5月6日,“中国式现代化的长三角实践”网上主题采访上海站活动调研浦东新区产业化之路。此次活动由中央网信

2023-05-07 13:54:49

天天看点:湖北电信:以“数字长江”推进大保护

​湖北石首江豚放归长江。“时刻牢记殷殷嘱托,守护一江碧水东流!”近日,在湖北荆州石首长江四大家鱼增殖放

2023-05-07 12:21:00

大眼鱼是什么鱼(大眼鱼是什么鱼?)

​大眼鱼学名叫做大眼黑鲷鱼,主要分布在我国南海、印度、菲律宾和太平洋的珊瑚礁海域中。体长一般在20-30厘

2023-05-07 11:44:23

台式win7电脑没有蓝牙功能如何安装_win7有蓝牙功能 全球新视野

​1、不是所有的电脑都有的,右键有发送文件至bluetooth的就有,你可以在控制面板硬件和声音里面看到添加bluet

2023-05-07 10:47:46

当前通讯!QQ群聊机器人头像_qq群聊机器人

​你们好,最近小品发现有诸多的小伙伴们对于QQ群聊机器人头像,qq群聊机器人这个问题都颇为感兴趣的,今天小

2023-05-07 09:55:32

贾巧姐是谁(贾巧姐)_视点

​1、红楼梦金陵十二钗——花语林黛玉(芙蓉) 薛宝钗(牡丹花)2、贾元春(昙花)3、贾探春(杏花)

2023-05-07 09:01:23

增加插混动力版本 广汽本田全新雅阁将于5月20日正式上市_当前速读

​日前,我们从官方渠道获悉,广汽本田全新一代雅阁将于5月20日在福建厦门宣布正式上市。此前,新车已开启限

2023-05-07 07:58:12

中国第一个目标飞行器空间实验室是哪里_中国第一个目标飞行器和空间实验室是_天天快报

​1、天宫一号。2、中国将于2010年—2011年底发射“天宫一号”目标飞行器,分别与神舟八号、神舟九号、神舟十

2023-05-07 06:44:08

有创意的群名称_好看的群名

​1、我们都是疯丫头,疯子小团队,我们一起疯,疯狂你我她,疯疯癫癫的姑娘们,一起疯一起闹。2、疯疯闹闹的

2023-05-07 05:02:27

天天视讯!造梦西游宣花红葫芦怎么合成 宣花红葫芦怎么合成

​今天来聊聊关于造梦西游宣花红葫芦怎么合成,宣花红葫芦怎么合成的文章,现在就为大家来简单介绍下造梦西游

2023-05-07 02:09:30

暑假社会实践报告心得3000字_暑假社会实践报告心得_天天精选

​1、也许专业不同但还是希望可以帮助你  暑期社会实践总结  实习可称为实践,学习。2、也许真是我们从大

2023-05-06 23:46:34

荣耀手环5幻彩屏健康运动手环 让你更健康的运动

​当一代又一代手环类产品并不满足于简单的心率、睡眠监测,而是不断朝着更加细分的运动健康领域不断深入赋能

2023-05-06 22:11:09

数智驱动一体化安全管控新探索-环球快报

​近年来随着智能化安全防控设备不断普及,公交安全防控水平得到了一定提升。但是公交安全事故依然屡见不鲜,

2023-05-06 21:07:08

京东计划今年发布千亿级大模型 先在核心产业落地再给合作伙伴_当前最新

​【京东计划今年发布千亿级大模型先在核心产业落地再给合作伙伴】“今年京东规划发布千亿级大模型,具体发布

2023-05-06 20:51:50

当前视讯!大师级工程任务_大师级工程在哪里学习啊

​1、联盟:高级工程技师–侏儒 宾斯匹德高级技师 铁炉堡大师工程技师–非侏儒、地精分支类(学习2

2023-05-06 19:51:24

共20家!湖北省2023年楚菜大师工作室名单公布

​根据省促进楚菜创新发展联席会议《关于印发楚菜大师工作室管理办法的通知》(鄂楚菜联办〔2022〕2号),湖

2023-05-06 18:55:33

天天资讯:《云朵国度》精灵技能是什么 精灵技能一览

​云朵国度精灵技能大致可分为【增益】【攻击】【防御】【回复】四种,效果可分为【被动】和【主动】。不同精

2023-05-06 18:21:52

广东省一项研究揭示:新冠再次感染发生率有多高?阳后症状如何?

​研究结果显示:感染过奥密克戎个体的再感染率显著低于感染过奥密克戎之前的变异株。大多数再次感染病例都有

2023-05-06 18:00:07

房子没办房产证离婚怎么办 每日信息

​一、房子没办房产证离婚怎么办房子没办房产证离婚的分割如下:有协议的,按照协议进行分割处理;没有协议双

2023-05-06 17:07:54

办托管班需要资质吗(办托管班需要哪些手续) 每日聚焦

​办托管班需要资质吗,办托管班需要哪些手续这个很多人还不知道,现在让我们一起来看看吧!1、儿童课后托管班

2023-05-06 16:22:20

每日热讯!银行宣布下调存款利率 来缓解银行负债压力 助于储蓄转化为消费

​近段时间,有多家银行宣布下调存款利率来缓解银行的负债压力,其中有渤海银行,浙商银行,恒丰银行等等,银

2023-05-06 16:08:32

全球播报:ChatGPT技术被用于“读心术”,我们需要担心吗?

​甚至不需要脑机接口

2023-05-06 15:30:00

岷县市场:黄芪采购力度不大 成交货源少

​今日黄芪大约有75-80吨货源出售,上货量略有减少。市场人流量基本稳定,常见的本地经营户及加工户随行采购

2023-05-06 14:53:39

全球热文:她说专辑下载 她说专辑

​今天来聊聊关于她说专辑下载,她说专辑的文章,现在就为大家来简单介绍下她说专辑下载,她说专辑,希望对各

2023-05-06 14:05:16

逾期了没钱换会影响到个人信用吗?信用卡欠款还不上会怎样?

​逾期了没钱换会影响到个人信用吗会。目前,我国对网络借贷行业进行了严格的管理,如果出现了逾期,将会

2023-05-06 13:46:34

商标转让的概念 前沿热点

​商标转让的概念商标转让是商标注册人在注册商标的有效期内,依法定程序,将商标专用权转让给另一方的行为。

2023-05-06 12:34:26