从我的校长生涯谈原型和原型链
简述引用类型
关于引用类型的赋值,上篇已经写过。
如果说引用类型是地点,我们操作的就是它的地址;
如果说引用类型是房子,我们操作的就是它的钥匙;
如果说引用类型是人物,我们操作的就是它的手机号;
如果说我们不用比喻,我们操作的就是它的引用。
至此,除了赞叹我的排比句是多么荡气回肠之外,你一定也发现:
- 引用类型就是一种有联系方式的数据类型
- 这种间接关系,使不同变量共享同一数据成为事实
例如
var a = {n: 1}
复制代码
用变量a
保存了{n: 1}
的引用,通过这个引用可以操作{n: 1}
,这个引用就是联系方式。
var b = a
复制代码
将a
的引用赋值给b
,变量b
也保存了{n: 1}
的引用,也可以操作{n: 1}
,这就是共享。
好比,你和你的房间的联系方式,就是房钥匙。
因为你有房钥匙,所以你才能够进房间,操作房间里面的东西。
如果路人甲默默复制一把,路人甲就可以和你一样,能够操作房间里的东西,这就是共享。
问题来了————
你俩虽然有你房间的钥匙,但是你俩拥有这个房间吗?
答案是肯定的。
即使是间接拥有,也是拥有。
好了,明白了上面的东西,原型就不是问题了。
我的校长生涯
在表达我对原型的理解之前,我想先讲一个发生在我身上的不真实的故事。
接下来,我将讲述我的一次创办学校的经历。
阶段一、白手起家
回到多年前。
我是小强,此时我正打算创建一所学校,所以大家也可以叫我小强校长。
首先,我要培养一个老师来替我上课,因为作为一个校长,我还有很多其它事情要做。
很快,我将多年的教学经验传授给一个叫孔仔的人,培养出第一个老师。
后来呢,孔仔也培养出一批又一批的学生。
阶段二、学科多样化
学校算是建成,孔仔也能完成教学任务,不断培养学生。
但是我发现一个问题,一个人的力量毕竟有限,虽然孔仔能完成基本教学,却没有精力在每个学科上做到专精。
这就导致,培养出来的学生没有专长,大多很普通。
终于有一天,我的学校得到许多好心人的赞助,我当时表示力度大点十分感谢。
钱多了,我就可以培养出更多的老师,不同特色的老师又可以培养出不同特色的学生,这不正是我的毕生所追求的东西吗?
于是,我的学校除了孔仔老师,又有了语文老师、数学老师、思想品德老师......
而且我还可以培养更多学科的老师。
阶段三、建设图书室
不知何时开始,有一些老师会找我申请一些教学方法的书,这我是十分支持的,可以说是有求必应。
随着申请的老师越来越多,我总结了一些很多老师会用到的教学方法的书,于是我就想:
不如我在自己办公室旁边建设一个图书室,把这些常用的书放在里面,老师们想看的时候来这里看不就行了。
很快有老师向我反映,他们其实也有相同的困扰,学生也会向他们申请一些课程相关的书,而且经常是相同的。
于是我决定,只要是老师,都要有一个自己的图书室,存放自己学生通常会用到的书或器材。
我也是老师,我是老师的老师。
所以,各科老师的图书室一般都存放各自文化知识方面的教材,而我的办公室存放的是教学经验方面的教材。
马上就要开工了!
可是我又发现,像《小学生必读》这类书,几乎在每个老师的办公室都有,我想:
不如把这类全校学生都读的书,放在同一个地方吧,这样就可以省下更多钱吃喝玩乐建设学校。
我第一想到的,就是孔仔老师,孔仔老师毕竟是我们学校的元老,同时他教的内容是最宽泛的、最不专门的,图书室应该相对空旷,所以就把《小学生必读》这类几乎所有学生都会看的书籍统一放到他的图书室吧。
于是我决定,在给每个老师建造图书室的同时,都建造一条隧道通往孔仔老师的图书室。
我的图书室也是那时候建的,所以我的图书室也有一条通往孔仔老师的隧道。
这样,我培养出来的老师,想看教学经验方面的书籍,就可以到我的图书室。
而我校老师培养出来的学生,想看自己学习方面的书籍,就可以到自己老师的图书室;
如果没有的话,就可以通过自己老师的图书室里的隧道,来到孔仔老师的图书室,看有没有想看的书籍。
这样我的学校就完美了,小强校长还是挺不错的哈?
原型和原型链
先把图放在这里。
javascript的培训方式
在javascript中,Function
扮演的就是校长的角色。
首先,他不想亲自去培养学生,所以他培养出了第一个老师孔仔。
Object
就相当于孔仔一样可以培养出学生,即通过new Object
可以创建对象。
但是,校长为了学生的多样化,又培养了语文老师、数学老师、思想品德老师等老师,而且还可以按需要培养更多老师;
同样,开发者想要创建多样化的数据、符合需要的对象,诸如String
、Number
、Boolean
这些函数对象也必不可少的,而且也可以根据需要写各种构造函数。
可以看到,校长培训出老师,老师再培训出学生;
Function
创建函数对象,函数对象再创建对象;
只不过javascript的培训方式是new
。
javascript的图书室
校长为了避免给每位老师买教学经验方面的书,所以创建了自己的图书室,用来让自己培养的老师共享这些资源;
而我们的Function
,也并不想把那些常用的方法都复制一份,保存到Object
、String
、Array
...以及后来新创建的N多构造函数当中,于是新增一个属性prototype(即原型对象),把一些公共的方法存在里面;
Function
让它创建出来的函数对象共享prototype
的方式,就是在通过new Function
创建函数对象的同时,会使
被创建的函数对象.__proto__ = Function.prototype
复制代码
比如,在创建Object
的时候,会使
Object.__proto__ = Function.prototype
复制代码
这个场景似曾相识?
没错,这就是我小强校长在创建自己的图书室后,将图书室钥匙送给孔仔老师一把的情景。
此后,孔仔老师就可以来我的图书室,查阅教学经验相关的书籍。
同理,Object
也因此可以访问Function
的prototype
,使用Function
为他们精心准备的函数对象的方法。
验证
Object.__proto__ === Function.prototype // true
复制代码
这里的true
表示的就是,钥匙已拿到,Object
已拥有Function
的prototype
。
接下来,可能会更多用到“拥有”这个词语
为什么呢?
虽然,根据开篇对引用类型的介绍,可知Object.__proto__ = Function.prototype
所做的事情:
无非就是,Function
把公共的方法都放在某个房间里,再将钥匙存在自己的属性prototype
里;
在赋值时,就是复制了一把prototype
里的钥匙,然后存在Object
的属性__proto__
中。
从这个过程可以看出,原型也不过是引用类型的赋值,就是通过一种联系方式间接拥有某个东西。
本篇文章开始说过,
即使是间接拥有,也是拥有。
首先,对引用类型的及其赋值的理解是必要的。
但是,在理解原型和原型链过程中,可以不必太关注引用类型赋值过程这种细节。
因为原型的目的,就是让实例们都拥有有一个公共区域,方便使用一些常用的方法。
所以类似Object.__proto__ === Function.prototype
这种吓人的结构,它要表达的不过就是这个意思:
前者已经拥有了后者提供的公共区域。
就像我的校长生涯那样,当我发现建图书室的作用之后,并不止为自己培养的老师建了图书室。
只要是老师,都要有一个自己的图书室,存放自己学生通常会用到的书或器材
这样,把一些学生的教材也变成共享,就又免得给每个学生都重复买教材。
也就是,不仅Function
创建函数对象时,会
被创建的函数对象.__proto__ = Function.prototype
复制代码
而且函数对象在创建对象时,会
被创建的对象.__proto__ = 创建对象的函数对象.prototype
复制代码
总结一下,只要new
的时候,就会
实例.__proto__ = 创建者.prototype
复制代码
即只要我创建了你,你就拥有了我的公共区域。
javascript的隧道
回顾我的校长生涯,在我即将开工给我和每位老师建图书室之前,我又想到:
每个老师的图书室里的书,也有很多是重复的,不如把这些重复的都放到元老级教师孔仔的图书室吧。
可是学生只能进各自老师的图书室,怎么让他们也能进孔仔老师的图书室呢?
还记得睿智的小强校长是怎么做的吗:
在建每件图书室的同时,修一条隧道可以到达孔仔老师的图书室,即Function创建对象的同时会
被创建的函数对象.prototype.__proto__ = Object.prototype
复制代码
例如
Array.prototype.__proto__ === Object.prototype // true
复制代码
没错,对于javascript
来说,Object
就是孔仔老师,Object
的prototype
就是孔仔老师的图书室。
为了减少不同函数对象的prototype
的重复,我们把很通用的对象的方法都放到Object
的prototype
中,并通过上述方法让其它函数都的prototype都拥有它。
这样,每个对象都拥有函数的prototype
,每个函数的prototype
又都拥有Object
的prototype
,那么每个对象也都拥有Object
的prototype
,即对象总能找到早就给它们精心准备好的方法的;
不同原型之间这个不依不饶的关系,就是原型链。
对于学生来讲,他们可以去的办公的总和、以及先后顺序,就相当于我们的原型链。
如图
关于“隧道”的建成,还有一些重要问题:
实际上,被创建的函数对象.prototype.__proto__ = Object.prototype
,并非Function做到的,而是Object做到的。
这里,Object
其实是使用的这一规则:
只要我创建了你,你就拥有了我的公共区域
因为javascript的创建方式是new
,要想实现被创建的函数对象.prototype.__proto__ = Object.prototype
,需要先有
被创建的函数对象.prototype = new Object()
复制代码
即所有对象的prototype
都是Object
创建的,都是Object
的实例。
其它函数对象的prototype
因此才能拥有Object
的prototype
,即实现这种效果
被创建的函数对象.prototype.__proto__ = Object.prototype
复制代码
那么,如果你是类比我的校长生涯来理解原型的,你就会想:
new在故事中不是“培训”的意思吗,这是不是说,其它的图书室都是孔仔“培训”出来的?
其实,这里我们自圆其说灵活理解就行了,毕竟例子只是用来帮助理解的。
所以,我们的“new”在这时候就是“创建”的意思。
在javascript中,所有对象的prototype
都是Object
创建的,那么
在我的校长生涯中,故事可能就是这样的:
我的校长生涯后记
这个时刻,学校还只是我(小强校长)和孔仔两个人。
我说,孔仔,为了实现资源的共享,我有一个想法。
孔仔说,啥想法?
我说,把你培养出来后,我已经很累了,但是我们这个学校将来肯定会得到好心人的捐助,也一定会培养更多的老师,老师们也一定需要教学经验方面的学习素材。如果每人我都发一套的话,就有点贵。所以我想给自己建造一个图书室,专门放这些资料,这样不管是你,还是以后培养出来的老师,就都可以在这里共享这些资源了。你觉得怎样,孔仔?
孔仔说,小强校长真抠门英明啊!您看这样如何,每个老师也都建设一个自己的图书室,这样,很多给学生的教材就不用重复买了,他们想用想看的时候去老师的图书室里找就行了,更省钱。
我说,只给学生们开一个图书室不可以吗,每个老师都有图书室会不会浪费?
孔仔说,不太好吧,毕竟不同学科的学生,使用教材的差异还是挺大的,不是很通用,还是建议每个老师都有各自的图书室,方便管理。
我说,有道理,但是总有一些通用的教材,比如《小学生必读》这种,没必要每个老师的图书室里都放一套,不够省钱。
孔仔说,您的意思是?
我说,放你那里吧。
孔仔已经跟不上我的思路,问,其他老师的学生都是去各自老师的图书室啊,这样只有我的学生能看到《小学生必读》这类书吧?
我说,这还不简单,每个老师的图书室都修一条隧道通向你的图书室。
孔仔沉默。
我说,修图书室的事情,就由你来负责吧!先给本校长来一个图书室吧。
孔仔说,不能,我要先给自己修建一个图书室,否则给你修建的时候不知道隧道通向哪里。
我说,好吧。
从此,每当我培养出一个老师,孔仔就帮忙修建一个图书室,同时挖一条隧道通往他自己的图书室。
我们的学校也越来越好。
其它你可能关心的事项
- Function.prototype.__proto __ === Object.prototype ?
对。建设每个图书室的时候,孔仔都挖隧道通向自己的办公室了,包括校长的办公室。
- Function.prototype.__proto === null ?
对。我们说好把通用资源都放在孔仔办公室,如今已经来到孔仔办公室,还想去哪里?
- 先有的Function还是先有的Object?
先有的Function。孔仔是我培养出来的,当然是先有的本校长。
- 先有的Function.prototype还是先有的Object.prototype?
先有的Object.prototype。不然孔仔修建图书室的时候,怎么知道把隧道通向哪里。
- constructor是什么?
原型的constructor放的是该原型所属的函数对象,即每个图书室里都放在该图书室所属老师的联系方式,比如电话号码。
- 小强校长帅吗?
颜值爆表。
如果你有其它关心的事项,可以发表评论或者联系我。
原文链接
从我的校长生涯谈原型和原型链相关推荐
- 浅谈javascript中原型(prototype)、构造函数、对象实例及三者之间的关系
转自:http://www.cnblogs.com/zhangwei412827/archive/2012/12/14/2816263.html 浅谈javascript中原型(prototype). ...
- queryrunner带参数的构造函数和不带参数的构造函数有什么区别_再谈构造函数、原型、原型链之间的关系...
前言 构造函数.原型.原型链作为ES5的内容,已经是老生常谈的问题了.首先说说为什么要再次拿起这个话题去说呢?这几天有空我会看一些源码,这些源码的底层实现考虑到兼容性还是来源于ES5,很多方法的封装以 ...
- 浅谈js原型和原型链
一.简述 对于javascript 对象(函数) 原型和原型链的理解,其实不那么难,简单来说,需要理解什么是原型,怎么访问原型,什么是原型链,怎么通过原型链去访问原型,就可以大概理清楚原型和原型链的基 ...
- 浅谈JS原型与原型链(一)
最近学习JavaScript原型与原型链的时候,被这块知识烧得脑壳疼,prototype与__proto__混淆不清.网上各种图解,都画的好复杂,绕老绕去,不明所以,看得越来越糊涂.还是亲自动手敲敲, ...
- 关于Android工程师转vue的三两事儿(10)--原型与原型链
说起原型和原型链接,着实让我这个前端菜鸟胡搞了好一阵子.虽然有点绕口的缘故,但是更多的还是自己比较浮躁带来的后果,这一块据说是前端的基础,看了很多遍才差不多有点头目.分享一下我领悟到的武林秘籍,希望能 ...
- 原型和原型链原型继承_我如何看待Flash的教训,拥有原型的未来
原型和原型链原型继承 Prototyping is critical part of UX process. Obviously, prototyping tools play significant ...
- 浅谈几种区块链网络攻击以及防御方案之其它网络攻击
旧博文,搬到 csdn 原文:http://rebootcat.com/2020/04/16/network_attack_of_blockchain_other_attack/ 写在前面的话 自比特 ...
- 浅谈几种区块链网络攻击以及防御方案之拒绝服务攻击
旧博文,搬到 csdn 原文:http://rebootcat.com/2020/04/14/network_attack_of_blockchain_ddos_attack/ 写在前面的话 自比特币 ...
- 浅谈几种区块链网络攻击以及防御方案之女巫攻击
旧博文,搬到 csdn 原文:http://rebootcat.com/2020/04/13/network_attack_of_blockchain_sybil_attack/ 写在前面的话 自比特 ...
最新文章
- Wamp与IIS同时在Windows7下运行解决方法
- Python3.x(windows系统)安装libxml2库
- 网站漏洞修复公司处理网站被篡改跳转到其他网站的解决办法
- Angular之组件的创建
- 数据库设计新手容易掉进的陷阱(不断更新中)
- Python高级——闭包与装饰器
- 如何安装tensorflow
- 关于SOA您该知道却不愿知道的十件事
- 【必收藏】台大李宏毅老师课程 | 资源汇总、笔记总结与索引
- tcpserver检测断开qt_QTcpServer或QTcpClient(在服务器端)知道,已连接的客户端现已断开连接...
- 全网最详细的纪录片观看&下载指南
- VOSviewer初步学习
- 如何在Chrome39添加360抢票王插件
- 662X芯片,662X三极管,贴片3.3V稳压IC规格书
- java蓝宇快递打印系统_蓝宇快递打印系统
- 国内就能读的中国人民大学与加拿大女王大学金融硕士,为职业发展的下一个阶段积蓄能量
- 联想笔记本linux不能启动无线网卡解决方法
- 淘宝PC自动化测试框架AutomanX-王超
- C语言程序设计——用户密码输入与判断
- Alpha阶段敏捷冲刺⑤
热门文章
- java 环信 rest api_[huanxin-sdk] 环信 Rest Api Node sdk
- 爱思考全面讲解CISP、CISSP、CISP-PTE之间都有什么区别
- 文件右键菜单没有“授予访问权限”选项
- 图片批量合成视频,并自动生成封面和配乐
- 格式化 U 盘,并还原分区
- 别怕,三招教你恢复TF卡分区后的数据
- 基于JavaWeb的汽车销售管理系统设计与实现 项目源码及数据库文件+论文
- 智慧树日均直播课堂超1.5万次 声网RTC技术保障学生“学的好”
- YOLOv5结构讲解
- Python实现FLV视频拼接