摘要:根据以上代码的变形,我们现在用面向对象思想来编写代码,创建构造函数,添加属性及方法。首先构造函数中的,由于是用关键字,因此指向,没问题。同时将指向当前点击的以参数形式传入中,这样一个面向对象思想的代码就写出来了。
本人自学前端近半年,js达到熟练的水平,面向对象思想、this指向有一定的了解,但是要用面向对象思想写代码就一脸懵逼了,最近看到某课堂的视频(里面广告嫌疑,就不说是啥了),觉得讲的很好,因此想和大家分享一下,希望那些和我一样有一定基础但是不知道怎么写的小伙伴也能愉快的写代码。
我们以选项卡的实现为例,先给出html的结构和样式:
111222333
我们先用过程式的编程思想来实现,然后将其改为面向对象思想的代码。
window.onload=function(){ //获取元素 var oParent=document.getElementById("div1"); var btns=oParent.getElementsByTagName("button"); var divs=oParent.getElementsByTagName("div"); //通过循环给每个btn添加点击事件 for (var i = 0; i < btns.length; i++) { btns[i].index=i;//存储当前btn的下标 btns[i].onclick=function(){ for (var i = 0; i < btns.length; i++) { btns[i].className=""; divs[i].style.display="none"; } this.className="active"; divs[this.index].style.display="block";//让对应当前btn的div显示 } } }
对于小白,也就是和我一样的人,一般就是写出上面的代码。现在我们要用面向对象的思想来改写,首先我们要对以上代码进行变形,使其不要出现函数的嵌套(如onload函数中就存在嵌套函数),变量可以改为全局变量,所以讲以上代码做出如下改变:变量变为全局变量,分出来一个init()函数和change()函数。
var oParent,btns,divs; window.onload=function(){ oParent=document.getElementById("div1"); btns=oParent.getElementsByTagName("button"); divs=oParent.getElementsByTagName("div"); init(); }; function init(){ for (var i = 0; i < btns.length; i++) { btns[i].index=i; btns[i].onclick=change; } } function change(){ for (var i = 0; i < btns.length; i++) { btns[i].className=""; divs[i].style.display="none"; } this.className="active"; divs[this.index].style.display="block"; }
根据以上代码的变形,我们现在用面向对象思想来编写代码,创建构造函数,添加属性及方法。
window.onload=function(){ var t1=new Tab(); t1.init(); }; function Tab(){ oParent=document.getElementById("div1"); btns=oParent.getElementsByTagName("button"); divs=oParent.getElementsByTagName("div"); } Tab.prototype.init=function(){ for (var i = 0; i < this.btns.length; i++) { btns[i].index=i; btns[i].onclick=change; } } Tab.prototype.change=function() { for (var i = 0; i < this.btns.length; i++) { btns[i].className=""; divs[i].style.display="none"; } className="active"; divs[btn.index].style.display="block"; };
将结构写出来,复制改过的代码,此时面向对象的思想已经初现端倪了。最后一步就是添加this了,因此将每个属性前面都添加this。
window.onload=function(){ var t1=new Tab(); t1.init(); }; function Tab(){ this.oParent=document.getElementById("div1"); this.btns=this.oParent.getElementsByTagName("button"); this.divs=this.oParent.getElementsByTagName("div"); } Tab.prototype.init=function(){ for (var i = 0; i < this.btns.length; i++) { this.btns[i].index=i; this.btns[i].onclick=change(); } } Tab.prototype.change=function() { for (var i = 0; i < this.btns.length; i++) { this.btns[i].className=""; this.divs[i].style.display="none"; } this.className="active"; this.divs[this.index].style.display="block"; };
以上代码就完成了吗?答案是否定的。为什么?还是因为this指向的问题。让我们一个一个来看。首先构造函数中的this,由于是用new关键字,因此this指向t1,没问题。init()方法,由于调用方式是t1.init(),this指向也为t1,没问题。那问题肯定是在change()方法中了,首先看看其调用形式this.btns[i].onclick=change();其this指向为this.btns[i],即当前点击的按钮,因此在change()内部,this.btns[i],this.divs[i]都不存在,因为btns和divs是t1的属性,其他的this如this.className指向是正确的,因此我们要改变this指向,一般都是将this指向改为指向对象,即t1。怎么改this指向?this指向与函数的调用方式有关,因此作出如下改变。
Tab.prototype.init=function(){ var This=this; for (var i = 0; i < this.btns.length; i++) { this.btns[i].index=i; this.btns[i].onclick=function(){ This.change(this); } } } Tab.prototype.change=function(btn) { for (var i = 0; i < this.btns.length; i++) { this.btns[i].className=""; this.divs[i].style.display="none"; } btn.className="active"; this.divs[btn.index].style.display="block"; };
首先在init()中,将this存在变量This中,用匿名函数中采用This.change(this);方式来调用方法。同时将this(指向当前点击的btn)以参数形式传入change()中,这样一个面向对象思想的代码就写出来了。
不知道大家看了会不会对大家有所帮助,现在我用面向过程思想写了一个拖拽的代码,大家可以试着将其改为面向对象的代码,代码如下,过程中会有几个坑,一个就是this指向的问题,另外一个就是事件函数的问题(ev只能出现在事件函数中)。最后跟大家分享一个小经验,事件和定时器很容易造成this指向的问题,因此在面向对象编程过程中要特别注意。
drag
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/82393.html
摘要:上篇文章分享了如何用面向对象思想编写选项卡,在文章最后留了一个拖拽的例子,希望大家可以试着写一下,现在我就谈谈我在这过程中遇到的一些问题和解决方法。通过以上方法来训练面向对象的编程思想,多练习,以后写出面向对象思想的代码就很简单了。 上篇文章分享了如何用面向对象思想编写选项卡,在文章最后留了一个拖拽的例子,希望大家可以试着写一下,现在我就谈谈我在这过程中遇到的一些问题和解决方法。(本文...
摘要:手把手教你做个人火的时候,随便一个都能赚的盆满钵满,但是,个人没有服务端,没有美工,似乎就不能开发了,真的是这样的吗秘密花园经典的中文手册。涵盖前端知识体系知识结构图书推荐以及入门视频教程,全的简直不要不要的了。 JavaScript 实现点击按钮复制指定区域文本 html5 的 webAPI 接口可以很轻松的使用短短的几行代码就实现点击按钮复制区域文本的功能,不需要依赖 flash。...
摘要:站在这个时间点上,我对自己之前三次失败的面试经历做了一次深度回顾。关于我第三次面试失败的经历,依然是与轮播图有关。当然,这次思特奇面试之旅,最后也是以失败告终,这也是我离进大厂最近的一次。 showImg(https://segmentfault.com/img/bVYQuP?w=528&h=513); 前言 时间的齿轮已经来到了2017年的11月份,距离2018年仅仅还剩下不到两...
阅读 1699·2021-11-02 14:47
阅读 3647·2019-08-30 15:44
阅读 1333·2019-08-29 16:42
阅读 1731·2019-08-26 13:53
阅读 934·2019-08-26 10:41
阅读 3458·2019-08-23 17:10
阅读 596·2019-08-23 14:24
阅读 1716·2019-08-23 11:59