您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關JavaScript的類出現了什么問題,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
雖然JavaScript類看起來一切正常,但若你用它一段時間,尤其是之前用過ES5的人,就有可能看見原型繼承演變成現行類模式的進程。
為什么呢?原型鏈出什么問題了?依我拙見,答案是一切正常。但技術界花費了數年的時間,迫使類的概念進入不同的結構和庫中,因此ECMA技術委員會決定無論如何都要添加它。
這有什么問題嗎?在我們已經擁有的原型繼承之上添加了一些組成,并決定將其稱為類,這反過來又讓開發人員以為他們正在處理一種面向對象的語言,而實際上它們并不是。
JavaScript沒有OOP的全面支持,因為它從來都不需要OOP。從表面看,現行類版式呈現出OPP范例,因為:
可以定義基本類、分類狀態和行為以及特殊經典語法。
可以把一種類沿用到另一種類。
可以定義屬性和方法的可行度,公共和私人均可。
可以為屬性定義獲得者和設置者。
可以忽略類繼承的方法。
當然還可以實例化各種類。
我之所以說類是語法糖,是因為盡管表面來看,類看起來非常面向對象,如果做一些超過領域可能性范圍的事,如定義一種涉及另外兩種類的類(這是目前不可能實現的事),需要使用如下代碼:
//Thehelper function functionapplyMixins(derivedCtor,baseCtors) { baseCtors.forEach(baseCtor => { Object.getOwnPropertyNames(baseCtor.prototype).forEach(name=> { let descriptor =Object.getOwnPropertyDescriptor(baseCtor.prototype, name) Object.defineProperty(derivedCtor.prototype, name, descriptor); }); }); } //The parent classes classA { methodA(){ console.log("A") } } classB { methodB(){ console.log("B") } } //The child class classC { } //Using mixins applyMixins(C, [A, B]) let o =newC() o.methodA() o.methodB()
我們需要做這個,因為無法編輯JS:
classA { methodA(){ console.log("A") } } classB { methodB(){ console.log("B") } } classCextendsA, B { }
在某些情況下,這種行為可能會派上用場,JavaScript的員工創建了上面的代碼片段,我只是刪除了額外的代碼,使它適用于普通JS。
但是樣本代碼的重要信息應該是applyMixins功能。即使不充分理解它的功能,也能發現,它用于評估各種類的原型屬性以復制和重分配方法和屬性。這是發現事實的全部證據:類只不過是在經過驗證的原型繼承模型之上的語法糖。
這說明應該停止用類嗎?并不是。理解它很重要,如果需要突破類能做和不能做的界限,將不得不處理原型來實現這一點。
如果現在的OOP模型不夠完美,只是原型繼承的抽象體,那么我們錯過了什么?什么使JS成為真正的OOP?
要解答這個問題,就先要看看JavaScript的功能,語言背后的團隊肯定要發明能把JavaScript轉換成JS的東西,來把JavaScript推到極限。這反過來也會限制它們的功能,但是,開始OOP愿望列表的一個好方法是查看它們與OOP相關的特性。
你馬上會注意到一個警告:目前JavaScript中缺失的一些OOP構造具有內在的類型檢查功能,在動態類型語言中沒有真正的意義,這可能是因為它們還沒有被添加。
這些是很好的結構,有助于定義類應該遵循的API。接口在無類型JS中可能會丟失,它的一個主要好處是,你可以為任何實現相同接口的類定義一個變量,并安全地調用它的任何方法。
interfaceAnimal { speak() } classDog implements Animal{ speak() { console.log("Woof!") } } classCat implements Animal{ speak() { console.log("Meau!") } } classHuman implements Animal{ speak() { console.log("Hey dude, what's up?") } } //if we had Interfaces in JS we could safely do: let objects = [newDog(), newCat(), newHuman()] objects.forEach(o => o.speak())
這在普通JS中是無法做到的。當然可以通過定義speak方法并覆蓋它的類來實現同樣的目的。但話又說回來,也可以在任何其他強OOP語言中這樣做,接口更加清晰和簡潔。
每當我嘗試用代碼進行全OOP時,肯定會錯過JS中的抽象類。抽象類定義并實現方法,但永遠不會被實例化。它是一種對可以擴展但不能直接使用的常見行為進行分組的方法。它絕對可以在當前的JS領域內實現,而不會造成太多的破壞。
靜態多態允許我們在同一個類中多次定義相同的方法,但是使用不同的簽名。換句話說,重復名稱,但要確保它接收到不同的參數。現在我們使用JS有了rest參數,這允許我們有任意數字,然而,這也意味著必須向方法中添加額外的代碼來處理這個層次的動態。
相反,如果可以更清楚地區分方法簽名,那么可以直接將相同行為的不同風格封裝到不同的方法中。
上邊版是無效的JS,但它的代碼更干凈,因此需要來進行心理分析的認知負荷也更少。然而,下邊版完全有效。它需要一些思維復合,周圍有更多的代碼,因為它不僅記錄日志(這應該是它的唯一目的),而且還試圖根據提供的參數決定如何記錄日志。
靜態多態性通常通過查看方法中接收的參數類型來實現。然而,由于JS的工作方式,我們知道這是不可能的。
已經有了公開的可見性,而且很快就得到了方法和屬性的私有可見性。下一步應該是添加受保護的可見性,如果你想要有一個合適的OOP體驗,這三者都是必要的。受保護的屬性和方法只能從類內部或它的一個子類中訪問(與私有可見性相反,私有可見性將訪問限制為只能訪問父類)。
我一直在努力把JS稱為OOP語言,直到我看到一種不用引用原型鏈就能處理類內部的方法,我才會繼續努力下去。為什么他們不能繼續擴展原型繼承模型,而不是給我們這個便宜的類版本呢?這是一個由來已久的問題。
看完上述內容,你們對JavaScript的類出現了什么問題有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。