问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

JavaScript之彻底理解原型与原型链

发布网友 发布时间:2024-09-05 23:11

我来回答

1个回答

热心网友 时间:2天前

1.前言

原型与原型链知识历来都是面试中考察的重点,说难不算太难,但要完全理解还是得下一定的功夫。先来看一道面试题开开胃口吧:

functionUser(){}User.prototype.sayHello=function(){}varu1=newUser();varu2=newUser();console.log(u1.sayHello===u2.sayHello);console.log(User.prototype.constructor);console.log(User.prototype===Function.prototype);console.log(User.__proto__===Function.prototype);console.log(User.__proto__===Function.__proto__);console.log(u1.__proto__===u2.__proto__);console.log(u1.__proto__===User.__proto__);console.log(Function.__proto__===Object.__proto__);console.log(Function.prototype.__proto__===Object.prototype.__proto__);console.log(Function.prototype.__proto__===Object.prototype);2.基础铺垫

JavaScript所有的对象本质上都是通过new函数创建的,包括对象字面量的形式定义对象(相当于newObject()的语法糖)。

所有的函数本质上都是通过newFunction创建的,包括Object、Array等

所有的函数都是对象。

3.prototype

每个函数都有一个属性prototype,它就是原型,默认情况下它是一个普通Object对象,这个对象是调用该构造函数所创建的实例的原型。

4.contructor属性

JavaScript同样存在由原型指向构造函数的属性:constructor,即Func.prototype.constructor-->Func

5.__proto__

JavaScript中所有对象(除了null)都具有一个__proto__属性,该属性指向该对象的原型。

functionUser(){}varu1=newUser();//u1.__proto__->User.prototypeconsole.log(u1.__proto__===User.prototype)//true

显而易见,实例的__proto__属性指向了构造函数的原型,那么多个实例的__proto__会指向同一个原型吗?

varu2=newUser();console.log(u1.__proto__===u2.__proto__)//true

其实学到这里就可以产生一些骚想法了,多个实例的__proto__都指向构造函数的原型,那么实例如果能通过一种方式,访问原型上的方法,属性等,就可以实现继承的效果。

我们继续更新一下原型与原型链的关系图:

6.原型链

实例对象在查找属性时,如果查找不到,就会沿着__proto__去与对象关联的原型上查找,如果还查找不到,就去找原型的原型,直至查到最顶层,这也就是原型链的概念。

就借助面试题,举几个原型链的例子:

6.1举例

u1.sayHello():u1上是没有sayHello方法的,因此访问u1.__proto__(User.prototype),成功访问到sayHello方法

u2.toString()u2,User.prototype都没有toString方法,User.prototype也是一个普通对象,因此继续寻找User.prototype.__proto__(Object.prototype),成功调用到toString方法

7.提高升华

学完上面那些,大多数面试题都可以做出来了,例如下面这种

functionA(){}functionB(a){this.a=a;}functionC(a){if(a){this.a=a;}}A.prototype.a=1;B.prototype.a=1;C.prototype.a=1;console.log(newA().a);//1console.log(newB().a);//undefinedconsole.log(newC(2).a);//2

但距离解决文章的最初的面试题还欠缺些什么,比如Function.__proto__===Object.__proto__、Function.prototype.__proto__===Object.prototype.__proto__等,接着我们来一一攻克它。

7.1Objcet.__proto__、Object.prototype、Object.prototype.__proto__

Object是构造函数,在第二部分我们讲过所有的函数都是通过newFunction创建了,因此Object相当于Function的实例,即Object.__proto__-->Function.prototype。

Object.prototype是Object构造函数的原型,处于原型链的顶端,Object.prototype.__proto__已经没有可以指向的上层原型,因此其值为null

//总结:Object.__proto__-->Function.prototypeObject.prototype.__proto__-->null7.2Function.__proto__、Function.prototype、Function.prototype.__proto__

Function.prototype是Function的原型,是所有函数实例的原型,例如上面讲的Object.__proto__

Function.prototype是一个普通对象,因此Function.prototype.__proto__-->Object.prototype

Function.__proto__:__proto__指向创造它的构造函数的原型,那谁创造了Function那?实践证明只存在Object.__proto__-->Function.prototypeFunction.proto-->Function.prototype

Function函数不通过任何东西创建,JS引擎启动时,添加到内存中

苦思冥想没得出结果,难道Function函数是猴子不成,从石头缝里面蹦出来的?于是我进行了一同乱七八糟的测试,没想到找出了端倪。

猜想:函数也是对象,那Function.__proto__会指向Object.prototype吗?但上文提到,Object是newFunction生成,Object.__proto__-->Function.prototype。如果真的如此指向,未免有些混乱,因此我去做了一下测试:

7.3升华

最后将原型与原型链方面的知识凝结成一张图:

所有函数(包括Function)的__proto__指向Function.prototype

自定义对象实例的__proto__指向构造函数的原型

函数的prototype的__proto__指向Object.prototype

Object.prototype.__proto__-->null

8.总结

知识的海洋往往比想象中还要辽阔,原型与原型链这边也反复的学过多次,我认为应该学的比较全面,比较完善了。但遇到这个面试题后,我才发现我所学的只不过是一根枝干,JS里面真的有很多深层次的宝藏等待挖掘。学海无涯,与君共勉。

最后再附赠个简单的面试题,提高一下自信:

varF=function(){}Object.prototype.a=function(){}Function.prototype.b=function(){}varf=newF();console.log(f.a,f.b,F.a,F.b);//f.__proto__-->F.prototype-->Object.prototype//F.__proto__-->Function.prototype-->Object.prototype

本文部分图源:渡一教育的学习资料

作者:战场小包

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
你喜欢外柔内刚的女孩还是外刚内柔的女孩? 男人喜欢外柔内刚还是外刚内柔型的女生 ...怎样涂好颜色啊,用彩笔还是彩铅啊...谢谢啦 ...也转动了,但是里面却没有动静,也没有风不过半分钟就关了,不是... 空调开机没反应,用遥控器点开关没反应,确定不是遥控器问题,空调重新插... 请问一下 上海电信的融合宽带一个月多少钱? 本人男 脸太圆想要瘦脸 不用药 女生初涉期货行业从事什么岗位比较好 为什么较少女生选择做期货交易 我现在就读大学,现在学校里新建一个期货专业,我在考虑转专业_百度知 ... JavaScript数组操作必须熟练运用的10个方法 javascript中的作用域和执行上下文 javascript和web的关系(javaweb和javascript) 前端基石:面向对象的细节知识(较长) new关键字相关知识点总结 javascript进阶知识4-正则表达式 javascript要学什么? javascript有哪些方面的知识? 兽皮痣右胳膊小臂长有黑色毛发胎记,哪家医院治疗最专业?【兽皮痣... 沈丘县胎记医院脸上有一点五分硬币那么大手术费多少钱 祛除面部胎记多少钱 有首歌里面有一句(几千年礼仪之帮)叫什么名字? ...其中有两句歌词是:五千年礼仪之邦,泱泱我大中华,天是坤,地是... 描写泉水的好段? 唯物主义是什么意思呀 唯物主义的意思 黄柏煮水的功效与作用 黄柏的功效与作用是什么 吕继宏出版专辑 离婚判决之后还能再起诉吗? 哈密瓜怎么去皮切块 哈密瓜怎么削皮 哈密瓜削皮方法 什么是肥厚型心肌病?可怕吗? 肥厚型心肌病临床上的特点 肥厚型心肌病的鉴别方法 肥厚型心肌病临床表现 肥厚型心肌病心脏彩超的表现 关于《琼明神女录》 底特律大都会国际机场简介 工作超十年被公司降职降薪,又唔出书面通知,只是收到口头通知,如何是好... ...口头通知降职降薪 然后公司又不出书面通告 这怎么办? 给老人送礼应该考虑哪些问题? 给老人送什么礼物比较好啊? 给80岁老人买礼物送什么好? 给老人送礼物送什么好? 朋友欠钱写了借条一直不还钱怎么起诉 保温杯总进虫子怎么办 我早上到办公室十有八九都发现保温杯里面有一个虫子进去,不知道从哪里... 狗狗要生了有什么征兆? 笼养猫咪有什么弊端?