閱讀說明:本文檔默認已有ES5相關(guān)基礎(chǔ)知識咧虎,包括構(gòu)造函數(shù)妻献、原型晚碾、繼承等
1.什么是面向?qū)ο?/h4>
-
面向過程POP VS 面向?qū)ο驩OP
<font color="#f00">面向過程</font>:分析出解決問題需要的步驟糯耍,然后用函數(shù)把這些步驟一步步實現(xiàn)扔字,使用的時候再依次調(diào)用。
面向過程POP VS 面向?qū)ο驩OP
<font color="#f00">面向過程</font>:分析出解決問題需要的步驟糯耍,然后用函數(shù)把這些步驟一步步實現(xiàn)扔字,使用的時候再依次調(diào)用。
? <font color="#f00">面向?qū)ο?lt;/font>:把事務分解成一個個對象温技,然后由對象之間分工與合作革为。
? 例:把大象關(guān)進冰箱,分別用面向過程和面向?qū)ο髞砻枋觯?/em>
? 面向過程:1. 打開冰箱
? 2. 大象放進去
? 3. 關(guān)上冰箱
? 面向?qū)ο螅合日页鲇心男ο蠖媪郏@些對象有哪些功能震檩?
? 1. 大象對象(進去)
? 2. 冰箱對象(打開、關(guān)上)
? 3. 使用大象和冰箱的功能
-
面向?qū)ο?/strong>
特性:封裝性 繼承性 多態(tài)性
優(yōu)點:易復用蜓堕,易維護抛虏,易擴展
缺點:沒有面向過程性能高(面向過程適合和硬件聯(lián)系緊密的東西,比如單片機)
總結(jié)&比喻:蛋炒飯--面向過程 | 蓋澆飯--面向?qū)ο?/p>
2.類和對象
面向?qū)ο罂梢孕稳莠F(xiàn)實世界的事物套才,事物分為具體的和抽象的兩種迂猴,比如手機這是抽象的概念,但我手中的這個iphone 11就是具體的一部手機背伴,是具體的概念沸毁。
面向?qū)ο蟮乃季S:
- 抽确逅琛(抽象)對象共用的屬性和行為組織(封裝)成一個<font color="#f00">類</font>(模板)
- 對類進行實例化,獲取類的對象
-
對象和類的含義
在JavaScript中息尺,對象是一組無序的相關(guān)屬性和方法的集合携兵,所有事物都是對象。例如:字符串掷倔、數(shù)值眉孩、數(shù)組、函數(shù)等勒葱。
ES6新增了一個概念類,使用class聲明巴柿,之后以這個類實例化對象凛虽。類抽象了對象的公共部分,泛指某一大類广恢。
3. class創(chuàng)建自定義類
如果不熟悉ES5的構(gòu)造函數(shù)概念的凯旋,建議先熟悉構(gòu)造函數(shù)以及對象的原型、繼承等知識钉迷,參考經(jīng)典紅寶書至非,這樣學習ES6中類的概念,會容易些糠聪。
類的創(chuàng)建和實例化:
class Star {
// 構(gòu)造函數(shù)荒椭,new創(chuàng)建對象時調(diào)用,可以接收傳遞過來的參數(shù),同時返回實例對象
constructor(uname) {
this.uname = uname
}
// 實例方法(相當于ES5中Star.prototype.say=function)
say() {
console.log(this.uname)
}
}
// 參數(shù)會傳給constructor構(gòu)造函數(shù)
const xz = new Star("肖戰(zhàn)")
const cxk = new Star("蔡徐坤")
xz.say()
console.log(xz.uname, cxk.uname)
4.什么是繼承
先看一個簡單的繼承的例子:
// 父類
class Father {
constructor(x, y) {
this.x = x
this.y = y
}
sum() {
console.log(this.x + this.y)
}
}
// 子類(通過extends關(guān)鍵字實現(xiàn)繼承舰蟆,繼承概念同ES5)
class Son extends Father {
// constructor函數(shù)可以沒有趣惠,但如果定義了,則必須在使用this之前 調(diào)用super函數(shù)身害,否則報錯味悄,因為子類沒有自己的this對象,而是繼承父類的this
constructor(x, y) {
// 調(diào)用父類的構(gòu)造函數(shù)
super(x, y)
}
}
var son = new Son(100, 5)
son.sum()
上面這個例子塌鸯,如果子類Son沒有constructor函數(shù)侍瑟,最終結(jié)果也是一樣的。因為子類如果不指定構(gòu)造函數(shù)丙猬,會默認添加以下構(gòu)造函數(shù):
constructor(...args) {
super(...args);
}
super關(guān)鍵字除了可以調(diào)用父類構(gòu)造函數(shù)涨颜,也能調(diào)用父類的普通方法:
class Father {
say() {
console.log("Father")
}
}
class Son extends Father {
say(){
// 調(diào)用父類的方法
super.say()
console.log("Son")
}
}
var son = new Son()
son.say()
繼承除了可以繼承父類中的方法,也可以擴展子類自己的方法淮悼,定義方式和類定義方法一樣咐低。
5.幾個注意點
類沒有變量提升,所以使用自定義類創(chuàng)建實例化對象時袜腥,必須先聲明這個類
類里面共有的屬性和方法加this使用
-
注意this的指向:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <button id="test">click!</button> </body> <script> var that var click_that var say_that class Star { constructor(name) { that = this this.anme = name this.btn = document.getElementById("test") this.btn.onclick = this.clickBtn } clickBtn() { click_that = this console.log(this) // button console.log(this.name) //undefined 因為這里的this指向的是button對象见擦,不是實例化對象 } say() { say_that = this } } var fa = new Star("肖戰(zhàn)") fa.say() console.log(that === fa) //true console.log(click_that === fa) //false console.log(say_that === fa) //true </script> </html>
上述代碼比較簡單钉汗,分別是打印了構(gòu)造函數(shù)以及兩個實例方法里this的指向,總結(jié)下:
constructor中的this指向的就是實例對象鲤屡,實例方法中的this指向损痰,記住一個原則,誰調(diào)用的就指向誰酒来。
比如上例中的click是button調(diào)用的卢未,this指向this.btn,say方法是實例對象調(diào)用的堰汉,所以this指向?qū)嵗龑ο骹a辽社。
我在github寫的一個關(guān)于面向?qū)ο蟮膶嵗?/a>,這個實例主要是一個tab翘鸭,包括刪除滴铅、添加、雙擊編輯功能就乓,采用的是面向?qū)ο蟮膶懛ā?/p>