教育新闻下载
顺德职业技术学院人文学院举办纪念“五四”运动100周年歌咏比赛
《深圳特区报》:深圳市合成生物学创新研究院揭牌
美媒盘点全美最难进20所大学 录取率极低
2018年美国研究生最新录取捷报大数据发布会
缺铁让女性很受伤 4种后果很严重!
360安全浏览器电脑版下载360安全浏览器正式版v10.1 beat最新版
友情链接
 
  教育孩子 您现在的位置 - 网站首页 > 教育孩子 > 弯道超车,5分钟快速理解构造器函数与原型对象之间的关系  
 

弯道超车,5分钟快速理解构造器函数与原型对象之间的关系

发布时间:2019-06-09
 

我们从数据库中查询出上面这几条记录,在JavaScript可能表示为一个二维数据,然后要创建出这三个人来,可能是下面这样的:constpeople=()//people=[[潘涛,male,1988-08-08],[...],[...]]for(leti=0;;i++){let[name,sex,birth]=people[i];people[i]={name,sex,birth,walk:function(){},run:function(){},jump:function(){},speak:function(){},coding:function(){}}}重复的资源占用上面大家已经发现,像上面这样去创建三个对象,walk、run、jump、speak、coding这五件能做的事情(方法),其实做法都一样,但是我们却重复的去描述该怎么做了,其实就占用了很多资源,所以,我们可能会像下面这样改进一下:constwalk=functionwalk(){};construn=functionrun(){};constjump=functionjump(){};constspeak=functionspeak(){};constcoding=functioncoding(){};for(leti=0;;i++){let[name,sex,birth]=people[i];people[i]={name,sex,birth,walk,run,jump,speak,coding}}不同的人共用相同的资源(方法)但是这个世界不止有人类对,人类相比于这个世界上的其它生物来讲,数量根本就值得一提,如果像上面这样,可能各种不同物种能做的事情都会要定义出不同的函数,蠕动肯定不是人类会去做的事情,但很多别的生物会做,那么为了代码管理方便,我们把人能做的所有事情都放在一个对象里面,这样就相当于有了一个命名空间了,不会再跟别的物种相冲突:constwhatPeopleCanDo={walk:function(){},run:function(){},jump:function(){},speak:function(){},coding:function(){}}for(leti=0;;i++){let[name,sex,birth]=people[i];people[i]={name,sex,birth,...whatPeopleCanDo}}原型但是,有的人可能我们并不知道他的sex信息是多少,有的也有可能不知道birth是多少,但是我们希望在创建这个人的时候,能给不知道的数据一些初始数据,所以,whatPeopleCanDo并不能完全的表达出一个人,我们再改进:constpeopleLike={name:,sex:unknown,birth:,walk:function(){},run:function(){},jump:function(){},speak:function(){},coding:function(){}}for(leti=0;;i++){let[name,sex,birth]=people[i];people[i]={...peopleLike,name:name||,sex:sex||,birth:birth||}}这样一来,我们就可以为不知道的属性加一些默认值,我们称peopleLike这个东东就为原型,它表示了像人类这样的物种有哪些属性,能干什么事情。

constpeoplePrototype={name:,sex:unknown,birth:,walk:function(){},run:function(){},jump:function(){},speak:function(){},coding:function(){}}for(leti=0;;i++){let[name,sex,birth]=people[i];people[i]={...peoplePrototype,name:name||,sex:sex||,birth:birth||,__proto__:peoplePrototype}}我们不再把人类原型里面的所有方法都绑定到某个人身上,而是像上面这样,用一个特殊的字段__proto__来指定:我的原型是peoplePrototype这个对象,同时,我们还制定了一个规则:如果你想请求我的某个方法,在我自己身上没有,那就去我的原型上面找吧,如果我的原型上面没有,那就去我的原型的原型上面去找,直到某个位置,没有更上层的原型为止像上面这样创建的people对象,有自己的属性,但是当我们去访问()方法的时候,其实访问的是people.__proto__.speak(),这是我们的规则。 更优雅的创建新新人类我们总不能在需要创建新人的时候,都像上面这样,自己去写一个对象,然后再手工指定它的原型是什么,所以,我们可以创建一个函数,专门用来生成人类的:constpeoplePrototype={name:,sex:unknown,birth:,walk:function(){},run:function(){},jump:function(){},speak:function(){},coding:function(){}}for(leti=0;;i++){let[name,sex,birth]=people[i];people[i]={...peoplePrototype,name:name||,sex:sex||,birth:birth||,__proto__:peoplePrototype}}现在这样我们只需要引入makePeople这个函数就可以随时随地创建新人了。

更优雅一点的改进显然,上面这样并不是最好的办法,定义了一个原型,又定义了一个原型对象,我们可以把这两个合并到一起,所以,就可以有下面这样的实现了:constPeople=functionPeople(name,sex,birth){letpeople={};=name||;=sex||;=birth||;people.__proto__=;returnpeople;}={name:,sex:unknown,birth:,walk:function(){},run:function(){},jump:function(){},speak:function(){},coding:function(){}}我们直接把创建人类的那个函数叫作People,这个函数有一个属性叫prototype,它表示用我这个函数创建的对象的原型是什么,这个函数做的事情还是以前那些事儿,创建临时对象,设置对象的属性,绑定一下原型,然后返回。 神奇的this我们除了人,还有别的动物,比如Tiger、Fish等,按上面的方式,在Tiger()或者Fish()函数里面都会建立不同的tiger或者fish名称的临时对象,这样太麻烦,我们把这种函数创建出来的对象,都可以统一叫作这个对象,也就是thisobject,不在关心是人是鬼,统一把所有的临时对象都叫thisObject或者更简单的就叫作:这个,即this。 constPeople=functionPeople(name,sex,birth){letthis={};=name||;=sex||;=birth||;this.__proto__=;returnthis;}当然,上面的这一段代码是有问题的,只是假想一样,这样是不是可行。

new到现在为止,我们发现了整个代码的演变,是时候引出这个new了,它来干什么呢?它后面接一个类似上面这种People的函数,表示我需要创建一个People的实例,它的发明就是为了解决上面这些所有重复的事情。

有了new之后,我们不需要再每一次定义一个临时对象,在new的上下文关系中,会在People函数体内自动为创建一个临时变量this,这个就表示即将被创建出来的对象。

同时,对于使用new创建的实例,会自动的绑定到创建函数的prototype作为原型,还会自动为People创建一个constructor函数,表示这个原型的创建函数是什么,所以,我们可以改成下面这样的了:constPeople=functionPeople(name,sex,birth){=name||;=sex||;=birth||;}=;=unknown;=;=function(){};=function(){};=function(){};=function(){};people=(p=newPeople(...p));总结new到底干了什么?当newPeople()的时候。

上一篇:四川高考史上最高分,清华学霸黎雨佳给家长的5大忠告,惊醒无数父母!高考奥赛父母
下一篇:贵州工业设计大赛作品征集通知
 
网站地图
版权所有:教育新闻www.36166j.com
地址:吉林市西环江路
吉ICP备16006号