您好!欢迎来到爱源码

爱源码

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

JavaScript系列的深度原型和原型链 《源码交易平台》

  • 时间:2022-09-02 09:02 编辑: 来源: 阅读:292
  • 扫一扫,手机访问
摘要:JavaScript系列的深度原型和原型链 《源码交易平台》
前言每次遇到新概念,我们可能会想到三个问题。这是什么?为什么会出现(为什么)?你能(如何)处理什么?这次,我们来看看原型和原型链的概念。要应对这3W(什么,为什么,怎样),首先要从js的面向对象入手...本文需要为面向对象准备计算机、大脑和一杯咖啡。什么是面向对象?我不需要多说。任何编程语言都有面向对象的概念,然后都有类的概念,但是ECMAScript(以下简称es)里没有,除了es6(其实就是语法糖,只是为了更像面向对象编程的语法)。但不代表因为es6有类,我们就可以刷掉原型和原型链的概念。由于es6一般都是在es5的基础上优化的,而且现在面试需要扎实的js基础,上次问了我几个继承方法,但答案并不完全正确...那么问题来了。既然没有阶级的概念,那么es是如何实现的呢?起初是以工厂模式实现的。这是什么?继续看下面的工厂模式。顾名思义,我们以玩偶制造为例。工厂要做一个娃娃:先做娃娃的对象(new Object()),然后分配娃娃的属性,比如颜色,身高,体重,最后做出来。代码如下:函数create doll(颜色、身高、体重){//制造工厂图案的函数。//创建一个玩偶对象o.color = color//color o . height = height;o.weight = weight有多高;//multiple o . say color = function(){//报告颜色警报(o . color);}返回o;}//为了表示是工厂模式,在变量名中加入f(factory:factory)let doll f1 = create doll f1(' orange ',20,10);//制作娃娃,调用上面的函数let doll f2 = create doll ('red ',30,10);//同上。将一个对象的所有属性和方法(所谓的自身信息)封装在一个工厂模式函数中,这样就可以制造多个对象。好处:减少大量重复代码。缺点:无法识别物体类型的问题。换句话说,无法判断一个对象来自哪个函数?我们以后再谈这个。正是因为这个缺点,才出现了构造器模式~构造器模式。什么是构造函数?其实写的跟普通函数一样,只是被new调用才叫做构造函数。代码如下:function doll (color,height,weight){//原来是一个普通的函数this.color = colorthis.height =高度;this.weight =重量;this . say color = function(){ alert(this . color);} }//为了表示是构造函数模式,在变量名后面加上cletdoll C1 = newdoll ('orange ',20,10);//用new调用,上面的函数调用构造函数let dollC2 = new Doll('red ',30,10);为了更好的识别构造函数,函数名要以大写字母开头,比如上面的大写字母D,然后相对于工厂模式去掉创建对象(让o = new Object());),直接给这个对象赋属性和方法,去掉return语句。 这样做的好处是工厂模式不能识别对象的类型。我们先来看调用构造函数和调用工厂模式的打印结果。我们要看文章,手工打代码,这样更容易理解~调用工厂模式的结果如下:调用工厂函数的结果如下:我们可以找出调用构造函数的结果,调用构造函数比工厂模式多了一个构造函数属性。这个属性指向Doll。为了证明这两个相等,我们可以打印出来看看:dollC1.constructor = = = Doll//真//那我们来看看工厂模式。doll f1 . constructor = = = create doll;//false,因为构造函数属性找不到createDoll函数,所以无法从createdoll函数判断。这就是工厂模式的缺点。为什么一定要判断对象类型?别急,这里面有很长的原因,你得一一解释。就像吃了好吃的,慢慢咀嚼才知道是什么味道。反之,吃的太快,就分不清味道了。这个本质没办法跟别人解释(面试官或者面试官写代码)~这个构造函数属性可以用来标识对象类型,但是小红书推荐用instanceof来判断。这是一个指示它可以是对象或构造函数的实例。看上图调用工厂模式和构造函数。工厂模式中的dollF1__proto__下有一个构造函数,指向对象;构造函数中dollC1__proto__下有两个构造函数,分别指向Object和Doll,然后我们用instanceof判断://构造函数模式dollC1 instanceof Doll//truedollC1 instanceof对象;//true//create doll的工厂模式dollF1实例;//falsedollF1 instanceof对象;//false所以这就是工厂模式和构造器模式的优劣比。至于为什么会有指向对象,所有创建的实例对象都有对象构造器。至于细节,可能会比较长。更有意思的是一个大人物智虎写的。推荐阅读《JavaScript世界万物的诞生》。但是,不要天真。没有什么是完美的,构造函数也是如此。不然我也不会讲原型和原型链。那么构造函数的缺点是什么呢?我们先来看看构造函数中的sayColor方法。该方法在多个实例对象上应该是相同的。但是,看看下面的代码:doll C1 . say color = = doll C2 . say color;//false结果打印出来的是false,嗯?为什么?调用构造函数后,会生成多个不同作用域的实例,相当于利用了多个实例的内存。不一定要有自己的方法,但不一定要有自己的方法。就好比说两个人要去旅行,需要准备点什么。因为卫生问题,你可以自己拿毛巾(属性)去了解,然后你和你的朋友要带沐浴露。你拿得越多,它就越重。换个角度,如果你不拿的话。在构造函数中也是如此。自带属性和方法越多,开发的内存就越多。于是,原型模式的概念就出现了(终于,走到了这一步)。原型模式(也叫原型)什么是原型模式?原型模式也可以叫分享模式(个人理解)。这几年分享不是很流行吗?共享单车、共享充电宝、共享汽车等。,一辆自行车可以被所有人共享,相当于一个原型模式可以被所有实例共享。不同的是自行车是要花钱的~前面说的构造器的属性和方法。这次在prototype模式中,将属性和方法移到构造函数的prototype对象中,用Prototype: function Doll(){}实现;doll . prototype . color = ' orange ';doll . prototype . height = 12;doll . prototype . weight = 6;doll . prototype . say color = function(){ console . log(this . color);}//为了表示原型模式,将普莱dollP1 = new Doll()添加到变量名中;doll P1 . say color();//橙色;let Doll p2 = new Doll();这是原型模式。前面提到的构造函数有一个缺点,多个实例对象的方法不一致。这一次,我们来看看多实例对象的方法是如何处于原型模式的。doll P1 . say color = = = doll p2 . say color;//真的,可以节省很多内存。示意图如下:原型模式。然后,我们来看看DollP1的打印结果。对比上图:dollP1dollP1.proto指向doll的原型对象(Doll.prototype)。如果你想读取颜色的值,你将在这个方向上查看原型对象的内部,并找到颜色。只需返回颜色的值。如果找不到,继续Object的原型对象。如果找不到,则返回“未定义”。我们来试试dollP1的color和nama属性:doll P1 . color;//orange doll P1 . name;//undefined但是,如果我想给dollP1的这个实例添加自己的属性,比如颜色,那么直接在dollP1上添加这个属性就很好了。代码如下:doll P1 . color = ' red ';doll P1 . color;//红色示意图如下:实例对象增加了一个属性。如果你阅读颜色的价值,你会首先在你自己的实例中搜索。如果你找到它,你将返回'红色'而不是在上层原型对象中搜索。 注意:即使实例对象上没有赋值,比如undefined,仍然会返回undefined。也就是说,实例对象只需要这个属性,这个属性的值无论赋值还是null都会直接返回。看起来很完美。不要这样想,我们来试试引用类型,比如array,把array的属性加到prototype对象上:doll . prototype . arr =[1//然后在实例对象dollP1中修改prototype对象的数组。会发生什么?doll P1 . arr . push(4);//4,返回数组Doll.prototype.arr的长度;//[1,2,3,4],嗯,原型对象的arr也改变dollp 2 . arr;//[1,2,3,4]你必须开始打代码,否则你就无法实现。结果实例对象和原型对象都被改变了,因为实例对象修改了原型对象的数组属性,所以原型对象失去了自己的准则。我想看看多个实例对象是否调用一个原型对象,如果原型对象的数组属性被修改,那么多个实例对象将全部具有相同的值。创建多个实例对象的意义是什么?所以这就是原型模式的缺点,那么什么是组合模式~组合模式呢?它是利用构造器模式和原型模式各自的特点组合成一个模式。构造器模式的特点是创建独立的实例,而原型模式的特点是共享,所以属性放在构造器模式,方法放在原型模式。代码如下:函数doll(颜色,身高,体重){ this.color = colorthis.height =高度;this.weight =重量;this.arr=[1,2,3];};doll . prototype . say color = function(){ console . log(this . color);}let doll1 = new Doll('orange ',14,6);doll P1 . say color();//橙色;let doll2 =新娃娃('红色',12,4);doll 1 . arr . push(4);//4 doll 1 . arr;//[1,2,3,4]doll 2 . arr;//[1,2,3];doll 1 . say color = = = coll 2 . say color;//true这样每个实例都可以有自己属性的副本,并共享prototype对象的方法,这样可以节省大量内存。 现在我们处理原型的3W问题,然后还有一个面向对象的特性,就是继承。在es中,我们如何处理继承?答案是原型链。看下面的原型链。什么是原型链?我们可以把这个概念拆分成“原型”+“链条”。原型是我们之前讲过的原型,而链是通向原型模式的链。我们之前讲过三个构造函数,原型对象和实例对象,对吧?如果创建了另一个构造函数,这个新构造函数的原型对象等于原构造函数的实例化对象呢?你怎么知道的?比如要造一个娃娃(娃娃目前只能做,娃娃默认为娃娃),现在又有了新的需求。制作动物玩偶,动物玩偶类似于人偶玩偶,可以借助玩偶构造器直接实例化。说白了就是继承doll的属性和方法,不需要自己创造同样的属性。代码如下:功能娃娃(颜色,身高,体重){/默认娃娃。this.height =高度;this.weight =重量;};doll . prototype . say color = function(){ console . log(this . color);}//构造函数animate doll(name){ this . name = name;}//借助Doll构造函数实例化AnimateDoll的原型对象。animate doll . prototype = new doll();animate doll . prototype . say name = function(){ return this . name;}let animate1=new AnimateDoll('猪');animate1.name//pig animate 1 . say name();//pig animate 1 . color;//undefined,由于没有传值,这个后面再说~ ~ animate 1 . say color();//同上。如果你想做一个新的抱枕娃娃,也可以是动物,也可以是人偶,那么你可以通过借用动物娃娃的构造函数来实例化抱枕娃娃的原型对象,这样你就可以继承动物娃娃和人偶的所有属性和方法,这三者之间的关系就成了原型链。当然不止三个~如前所述,animate.color结果打印为未定义。由于没有传递值,所以需要使用call来继承Doll的属性,然后将参数赋给相应的属性。代码如下:函数doll(颜色,身高,体重){ this.color = colorthis.height =高度;this.weight =重量;};doll . prototype . say color = function(){ console . log(this . color);}函数AnimateDoll(名称,...args){ Doll.call(this,...args);//添加新行this.name = name} animate Doll . prototype = new Doll();animate doll . prototype . say name = function(){ return this . name;}let animate1=new AnimateDoll('猪','粉红',20,10);animate1.name//pig animate 1 . say name();//pig animate 1 . color;//pink animate 1 . say color();//pink animate 1 . height;//20 animate 1 . weight;//10继承方法不仅仅是这个原型链,其余的也是。有兴趣可以自己去看看小红书或者google~我之前提过一个问题“为什么一定要判断对象类型?”如果没有对象类型,就无法判断一个对象指向哪一个,就无法实现继承方法。 就是这样~觉得不错,求个赞~觉得不足,求个建议~续杯


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【域名/主机/服务器|】qq邮箱提醒在哪里打开(2024-06-04 18:58)
【技术支持|常见问题】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)

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