因為之前學過類,是以聽起來還比較輕松,但是初學者(以前的我 - >-)可能會有點懵逼,建議先在網上好好查閱資料
面向對象程式設計
面向過程程式設計
面向過程程式設計就是分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實作,使用的時候再一個一個依次調用就可以.面向過程,就是按照我們分析好的步驟,按照步驟解決問題
面向對象程式設計
面向對象是把事物分解成為一個個對象,然後由對象之間分工與合作.面向對象是以對象功能來劃分問題,而不是步驟
在面向對象程式開發思想中,每一個對象都是功能中心,具有明确分工.
面向對象程式設計具有靈活,代碼可複用,容易維護和開發的優點,更适合多人合作的大型軟體項目.
面向對象的特性
- 封裝性
- 繼承性
- 多态性
類(class)
(仿佛回到了學Python的時候...)
在ES6中新增了類的概念,可以使用class關鍵字聲明一個類,之後以這個類來執行個體化對象.
類抽象了對象的公共部分,它泛指某一大類
對象特指某一個,通過類執行個體化一個具體的對象.
面向對象的思維特點
- 抽取(抽象)對象共有的屬性和行為組織(封裝)成一個類(模闆)
- 對類進行執行個體化,擷取類的對象
建立類

建立執行個體
var xx = new name( )
類必須要用new執行個體化對象
完整寫法:
class name {
// class body
}
var xx= new name();
複制
類constructor構造函數
constructor()方法是類的構造函數(預設方法),用于傳遞參數,傳回執行個體對象,通過new指令生成對象執行個體時,自動調用該方法.如果沒有顯示定義,類内部會自動給我們建立一個constructor()
隻要有new就會自動調用constructor( )這個方法.我建立ldh對象時将"劉德華"這個參數傳遞給了uname,而uname又指派給了this.uname;this指向的是我們建立的執行個體,this.uname就是我建立的執行個體ldh的uname.我将"劉德華"指派給我們的執行個體的uname,是以ldh這個執行個體化對象的uname就是"劉德華".(有點繞...),反正就是我建立了一個明星類,然後執行個體化了一個ldh對象,并且給他的uname指派為劉德華.
注意:
- 通過class關鍵字建立類,類名我們還是習慣性定義首字母大寫
- 類裡面有個constructor函數,可以接受傳遞過來的參數,同時傳回執行個體對象(是以不用return就能列印出對象)
- constructor函數,隻要 new 生成執行個體時,就會自動調用這個函數.如果我們不寫這個函數,類也會自動生成這個函數
- 生成執行個體new不能省略
- 最後注意文法規範,類名後面不要加小括号,生成執行個體,類名後面加小括号,構造函數不需要function.
類添加方法
注意: 類裡面的方法不需要寫function;多個方法函數之間不需要逗号分割!!
類的繼承
子類可以繼承父類的一些屬性和方法
下面我們看看這個情況:
子類繼承了父類的方法,自己重寫了屬性,但是想繼續使用父類的方法sum()
按理來說應該得到3這個答案,但是結果是報錯
這是因為我們sum()方法中的this指向的都是父類的對象,但是子類重寫了,this指向的就是子類的對象了,是以當然會報錯
這個時候就要用到super()了
super關鍵字
super關鍵字用于通路和調用對象父類上的函數.可以調用父類的構造函數,也可以調用父類的普通函數.
我們隻要将函數這樣修改就可以了
這樣就可以啦
super()不僅能繼承構造函數,也能繼承普通函數
我們看下面的例子:
毫無疑問會輸出"我是兒子?imageView2/2/w/1620",因為兒子重寫了這個方法
- 繼承中,如果執行個體化子類輸出一個方法,先看子類有沒有這個方法,如果有就先執行子類的.
- 繼承中,如果子類裡面沒有,就去查找父類有沒有這個方法,如果有,就執行父類的這個方法(就近原則)
改成這樣即可:
現在我們寫一個子類,繼承父類的加法運算,同時有自己的減法運算方法:
但是這樣會報錯:
在這裡要注意,利用super調用父類的構造函數,super必須在子類this之前調用!!!
應修改為:
這樣就沒問題了
注意:
- 在ES6中類沒有變量提升,是以必須先定義類,才能通過類執行個體化對象
- 類裡面的共有的屬性和方法一定要加this使用.
- constructor裡面的this指向執行個體對象,方法裡面的this指向這個方法的調用者
注意: sing這個函數如果不加括号就不會立即調用,加了就會立即調用:
比如這個方法,我們是要點選了才調用,加了就會立馬調用
this指向問題
在constructor()方法中,this指向的是我們new出來的執行個體化對象
順便解決了前面的問題,為什麼列印出來的uname是undefined:因為this指向的是button,button的uname當然沒有定義,是以就是undefined.
那要怎樣才能點選button以後擷取到constructor裡面的uname呢?隻要在外面聲明一個全局變量,再将this指派給它就可以了.
接下來就是案例時間: tab欄切換
需求:
是以我們可以先寫一個Tab類出來,裡面具有多種功能(方法):
擷取要操作的元素
初始化綁定事件
在點選時就切換類,給點選的li和section設定類名.
我們在前面講過,想要調用constructor()裡面的屬性,需要聲明一個全局變量,是以我們聲明一個that:
類裡面的方法隻能由對象本身調用,是以才要将this指派給that
現在切換功能就基本實作了,接下來是添加功能
我們先将添加的按鈕綁定事件:
接下來要做的:
初步做出來是這樣的
我們先來看看效果:
肯定是有bug的,後面的新增的li并沒有切換功能,且下面的内容也全部出來了,這是因為我們一開始擷取的li和section都是本身存在的,初始化時都綁定了事件,但是我們後來生成的li和section都沒有被擷取,自然也沒有綁定事件
然後在元素都添加完以後調用init初始化一遍,新增的元素就綁定了事件
那麼添加功能就完成啦,現在做删除的功能
首先還是擷取元素:
然後在循環中綁定事件:
編輯删除方法:
但是這個時候我們點選添加按鈕時卻出錯了:
分析一下:
當我們頁面一加載,就擷取所有的關閉按鈕,一開始隻有三個,但是當我們點選添加按鈕時,這時候調用了addTab(), addTab裡面又有init(),是以目前有4個li,但是每個li都要周遊:remove的關閉按鈕隻有三個.
是以解決方案就是将擷取關閉按鈕元素的代碼寫在update方法裡面:
然後是删除方法:
有點難qwq...最後一個短路運算也是我随便試出來的..
終于到了最後的編輯功能!
編輯事件
很幸運,section的做法和span一模一樣,隻要加一行代碼就可以了
這個案例到這裡就結束啦,真的很累,也學到了很多!!!現在看看功能
切換:
添加和删除
編輯:
困暈了,休息一下,到時候将這個案例複習一遍!(想想就好累...)