响亮的标题:一个万能的,保底的。面向过程改写成面向对象的方法
前提朗读:很多刚接触js面向对象的时候都不知道如何能快速的写出一个面向对象的程序,这个是必然的现象,不是每一位学js的一上来就会写面向对象的程序。小编这里介绍的方法属于一个面向过程到面向对象的过度期间,(这里要明白面向对象的一些常识:构造函数创建出对象,对象.属性,对象.方法)
一:改写前提步骤:
1.前提:面向过程中的所有代码都在window.onload 里面
2.面向过程里面所有的函数都领到外面去(不能有函数嵌套)
3.提出共同的变量为全局变量(可以有全局变量 当有两个以上的函数都用到了共同的一个变量的话--把这个变量提出来变成全局变量)
小总结4:替换过程(注意this的使用)
面向过程 | 面向对象 |
---|---|
onload(初始化整个程序) | 构造函数(初始化对象) |
全局变量 | 属性(对象.属性) this.属性 |
函数 | 方法(构造函数.原型.方法) 构造函数.prototype.方法 |
** 备注重点:
改错:this,事件,闭包,传参
重点:通过闭包传递this
**小编提示:
面向对象中70%以上都会用到this这个关键字,所以要想使用好面向对象,必须弄明白this
二:案例展示:(不注重要是布局)
1.面向过程案例展示
<script> window.onload=function () { var oDiv=document.getElementById('div1'); //获取父级 var aBtn=oDiv.getElementsByTagName('input'); //获取oDiv下的所有的input var aDiv=oDiv.getElementsByTagName('div'); //获取oDiv下的所有div var i=0; //预先设置变量 i //思路:清除所有的input元素上的class,并影藏对应的div。 //然后:添加当前点击的那个input的class。并显示对应的那个div for(i=0;i<aBtn.length;i++) { aBtn[i].index=i; //给每一个input元素新增加一个属性index aBtn[i].onclick=function () { //思路:先清除所有的input上面的class,并隐藏input对应的div for(i=0;i<aBtn.length;i++) { aBtn[i].className=''; aDiv[i].style.display='none'; } //思路:然后给当前点击的那个input添加上class = active,并显示出input对应的那个div this.className='active'; aDiv[this.index].style.display='block'; }; } }; </script> <div id="div1"> <input class="active" type="button" value="教育" /> <input type="button" value="财经" /> <input type="button" value="aaa" /> <div style="display:block;">11111</div> <div style="display:none">22222</div> <div style="display:none">33333</div> </div>
2.面向过程里面所有的函数都领到外面去(不能有函数嵌套)。提出共同的变量为全局变量
<script> var aDiv = null; //声明全局变量 var aBtn = null; //声明全局变量 window.onload=function () { var oDiv=document.getElementById('div1'); //获取父级 aBtn=oDiv.getElementsByTagName('input'); //获取oDiv下的所有的input aDiv=oDiv.getElementsByTagName('div'); //获取oDiv下的所有div var i=0; //预先设置变量 i //思路:清除所有的input元素上的class,并影藏对应的div。 //然后:添加当前点击的那个input的class。并显示对应的那个div for(i=0;i<aBtn.length;i++) { aBtn[i].index=i; //给每一个input元素新增加一个属性index aBtn[i].onclick=tab; } }; function tab(){ //思路:先清除所有的input上面的class,并隐藏input对应的div for(i=0;i<aBtn.length;i++) { aBtn[i].className=''; aDiv[i].style.display='none'; } //思路:然后给当前点击的那个input添加上class = active,并显示出input对应的那个div this.className='active'; aDiv[this.index].style.display='block'; }; </script> <div id="div1"> <input class="active" type="button" value="教育" /> <input type="button" value="财经" /> <input type="button" value="aaa" /> <div style="display:block;">11111</div> <div style="display:none">22222</div> <div style="display:none">33333</div> </div>
3,this修改后
<script> window.onload = function(){ var oTab = new TabSwitch('div1'); } function TabSwitch(id) //构造函数 { var oDiv=document.getElementById(id); //获取父级 this.aBtn=oDiv.getElementsByTagName('input'); //获取oDiv下的所有的input this.aDiv=oDiv.getElementsByTagName('div'); //获取oDiv下的所有div var i=0; //预先设置变量 i //思路:清除所有的input元素上的class,并影藏对应的div。 //然后:添加当前点击的那个input的class。并显示对应的那个div var _this = this; //this表示new出来的对象 for(i=0;i<this.aBtn.length;i++) { this.aBtn[i].index=i; //给每一个input元素新增加一个属性index this.aBtn[i].onclick=function(){ _this.tab(this); // ** _this表示通过构造函数new出来的对象。 this表示调用事件onclick的对象--> 按钮input } } }; TabSwitch.prototype.tab = function(oBtn){ //思路:先清除所有的input上面的class,并隐藏input对应的div for(i=0;i<this.aBtn.length;i++) //this表示通过构造函数new出来的对象 { this.aBtn[i].className=''; this.aDiv[i].style.display='none'; } //思路:然后给当前点击的那个input添加上class = active,并显示出input对应的那个div oBtn.className='active'; this.aDiv[oBtn.index].style.display='block'; }; </script> <div id="div1"> <input class="active" type="button" value="教育" /> <input type="button" value="财经" /> <input type="button" value="aaa" /> <div style="display:block;">11111</div> <div style="display:none">22222</div> <div style="display:none">33333</div> </div>
咱使用this来讲2个面向对象的小案例:this啥时候会出问题。
1:在定时器里面
2:在事件里面(通过闭包的方式把this传过去)
面向对象this案例一(正常现象):
<script> function Aaa(){ this.a = 55; console.log(this) //表示new出来的对象 } Aaa.prototype.show = function (){ alert(this.a) console.log(this) //表示new出来的对象 } var obj1 = new Aaa(); obj1.show(); // 55 </script>
面向对象this案例二(定时器里面的this):
<script> function Aaa(){ this.a = 55; setInterval(this.show, 3000); //this为 window 证明了定时器里面的this不正常为window console.log(this) //构造函数对象 } Aaa.prototype.show = function (){ alert(this) //表示为 window } var obj1 = new Aaa(); </script> 改进方法 <script> function Aaa(){ this.a = 55; var _this = this ; //this为构造函数的对象,然后赋给一个变量 _this setInterval(function(){ _this.show(); //_this为 构造函数的对象 }, 3000); console.log(this) //构造函数对象 } Aaa.prototype.show = function (){ alert(this) //构造函数的对象 } var obj1 = new Aaa(); </script>
面向对象this案例三(事件里面的this):
<script> function Aaa(){ this.a = 55; document.getElementById('odiv1').onclick = this.show; } Aaa.prototype.show = function(){ alert(this.a); //打印出:undefone 因为:this为 input按钮,但是input按钮上根本没有a这个属性,所以提示为undefine console.log(this); // this为 input按钮 } window.onload = function(){ new Aaa(); } </script> 改进后 <script> function Aaa(){ this.a = 55; var _this = this; // _this = this = 构造函数的对象 document.getElementById('odiv1').onclick =function(){ _this.show(); //_this 表示为构造函数的对象 } } Aaa.prototype.show = function(){ alert(this.a); //55 } window.onload = function(){ new Aaa(); } </script> <input id="odiv1" type="button" value="按钮">