前端技術(shù)尤其是JavaScript,經(jīng)常被后端覺得不是正經(jīng)編程語言,大多數(shù)是因為JavaScript是基于函數(shù)的語言,因此潛在上使得它在使用和發(fā)展上有所局限。
我記得在90年代末和21世紀(jì)初,JavaScript主要用于使html頁面更加動態(tài)。比如實現(xiàn)一些彈窗,跑馬燈之類的視覺效果。
現(xiàn)在,我們有很多框架,庫,甚至后端系統(tǒng)都在使用JavaScript。用JavaScript開發(fā)一個移動應(yīng)用和桌面應(yīng)用程序-在以前是聞所未聞的,但如今,這些我們經(jīng)常聽說甚至已經(jīng)投入使用了。現(xiàn)在我們還可以用JavaScript實現(xiàn)跨平臺開發(fā)!
JavaScript無處不在,你可以使用JavaScript輕松完成很多有趣的東西。但隨之而來的是潛在的長期問題。許多JavaScript開發(fā)者并沒有像java開發(fā)者一樣習(xí)慣使用面向?qū)ο缶幊蹋蛘哒f沒有面向?qū)ο缶幊踢@方面的訓(xùn)練。這很正常,因為我們經(jīng)常為了追趕進度完成手頭的工作,忽略了一些我們還不知道的內(nèi)容
什么是面向?qū)ο缶幊蹋?/h3>
面向?qū)ο蟮木幊淌且环N思想,一種心態(tài)。它背后的想法是,你為你想象中的對象創(chuàng)建了一個藍圖,然后一次又一次地調(diào)用它來完成各種各樣的功能。每次你想使用一個對象時,你必須先創(chuàng)建它這樣它才會存在,然后設(shè)置它的屬性,以便使用附加到它的功能。這些功能被稱為“方法”。
例如,一個CustomerOrder對象可能附加了一個GET:Order Details功能(又名方法)。
//基于類
class CustomerOrder{
constructor(customerId,orderId){
this.customerId = customerId;
this.orderId = orderId
}
get orderDetails(){
return this.pullOrderDetails();
}
pullOrderDetails(){
//一些操作
return
}
}
const order_1 = new CustomerOrder(87873,"Cus-001")
console.log(order_1.orderDetails)
我們來看另一個基于函數(shù)的方法:
//基于函數(shù)
const customerId = 8787
const orderId = "Cus-001"
function pullOrderDetails(customerId,orderId){
//一些操作
return
}
console.log(pullOrderDetails(87873,"Cus-001"))
上面的問題在于,函數(shù)的數(shù)量多起來時,很快就會變得混亂。雖然將所有內(nèi)容都編寫為函數(shù),然后根據(jù)需要來調(diào)用,在一開始可能會很方便,但是日積月累,函數(shù)之間的關(guān)聯(lián)關(guān)系錯綜復(fù)雜,一旦發(fā)生變更,你可能需要修改很多函數(shù),也會引起很多未知問題。
可能有些難理解,我們看下面的圖(使用類的情況):
constructor是設(shè)置變量的地方,Getter和setter方法是類做事的入口。使用什么函數(shù)以及如何使用它們都是隱藏的。每次創(chuàng)建一個新對象時,整個類及其方法都會被“克隆”,并可訪問需要的內(nèi)容。發(fā)生變更時,我們也只需要在類上一次修改,便可以全局生效。
我們再看下面的圖(使用函數(shù)的情況)
當(dāng)我們用一堆松散的函數(shù)編寫代碼時,它的更改范圍通常沒有定義。依賴項注入是使函數(shù)正常工作所必需的,而一個函數(shù)常常需要另一個函數(shù)才能正常工作。從表面上看,基于函數(shù)的編程可能一開始看起來很簡單,但從長遠來看,維護它是一個邏輯上的噩夢。
使用面向?qū)ο缶幊蹋恍枰{(diào)用getter和setter方法來訪問黑盒功能。作為類的消費者,你不需要知道它是如何工作的。你只需要知道它是有效的。
為什么我們要在JavaScript中采用面向?qū)ο缶幊?/h3>
上面的兩幅圖能看出來,過度依賴基于函數(shù)的編程可能很快就能完成任務(wù),但是長遠來看,這會存在很高的風(fēng)險。
隨著代碼量的增長,你就需要改變組織代碼的思維方式,并考慮采用面向?qū)ο蟆Ec通過一系列依賴注入串在一起的函數(shù)相比,對象的則更容易追蹤和掌握。
下面的代碼是基于函數(shù):
你會需要知道整個調(diào)用鏈,以便弄清楚如何實現(xiàn)你的目的。當(dāng)然也很亂,不易理解。
基于函數(shù)的編程的問題是,鏈的中斷可能導(dǎo)致整個流程的失敗。對于對象,一個被破壞的方法不會(也不應(yīng)該)影響類的其他部分。
下面的代碼是基于類(面向?qū)ο螅?/p>
這種方法,可能代碼量不會少多少,但你可以復(fù)用它,而不需要寫很長的調(diào)用鏈。
當(dāng)你思考問題時,是基于類,而不是一系列相互關(guān)聯(lián)的函數(shù)時,代碼自然會減少出現(xiàn)問題的風(fēng)險。因為每一次依賴注入都會增加一次潛在錯誤的可能,而且尋找錯誤時,也會花費更多的時間和精力。、
最后
面向?qū)ο缶幊淌且环N主動的行為,你可以選擇使用,也可以選擇不使用。隨著前端體系的日益龐大,代碼量和應(yīng)用場景也遠超于從前,我們更需要思考面向?qū)ο缶幊痰闹匾浴?/p>
面向?qū)ο缶幊痰馁Y料:
https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Objects/Object-oriented_JS