響亮的標題:一個萬能的,保底的。面向過程改寫成面向對象的方法 前提朗讀:很多剛接觸js面向對象的時候都不知道如何能快速的寫出一個面向對象的程式,這個是必然的現象,不是每一位學js的一上來就會寫面向對象的程式。小編這裡介紹的方法屬於一個面向過程到面向對象的過度期間,(這裡要明白麵向對象的一些常識:構造 ...
響亮的標題:一個萬能的,保底的。面向過程改寫成面向對象的方法
前提朗讀:很多剛接觸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="按鈕">