自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JavaScript的類出現(xiàn)了什么問題?

開發(fā) 前端
雖然JavaScript類看起來一切正常,但若你用它一段時(shí)間,尤其是之前用過ES5的人,就有可能看見原型繼承演變成現(xiàn)行類模式的進(jìn)程。

 本文轉(zhuǎn)載自公眾號(hào)“讀芯術(shù)”(ID:AI_Discovery)

雖然JavaScript類看起來一切正常,但若你用它一段時(shí)間,尤其是之前用過ES5的人,就有可能看見原型繼承演變成現(xiàn)行類模式的進(jìn)程。

[[389233]]

為什么呢?原型鏈出什么問題了?依我拙見,答案是一切正常。但技術(shù)界花費(fèi)了數(shù)年的時(shí)間,迫使類的概念進(jìn)入不同的結(jié)構(gòu)和庫中,因此ECMA技術(shù)委員會(huì)決定無論如何都要添加它。

這有什么問題嗎?在我們已經(jīng)擁有的原型繼承之上添加了一些組成,并決定將其稱為類,這反過來又讓開發(fā)人員以為他們正在處理一種面向?qū)ο蟮恼Z言,而實(shí)際上它們并不是。

類僅僅是語法糖(syntactic sugar)

JavaScript沒有OOP的全面支持,因?yàn)樗鼜膩矶疾恍枰狾OP。從表面看,現(xiàn)行類版式呈現(xiàn)出OPP范例,因?yàn)椋?/p>

  • 可以定義基本類、分類狀態(tài)和行為以及特殊經(jīng)典語法。
  • 可以把一種類沿用到另一種類。
  • 可以定義屬性和方法的可行度,公共和私人均可。
  • 可以為屬性定義獲得者和設(shè)置者。
  • 可以忽略類繼承的方法。
  • 當(dāng)然還可以實(shí)例化各種類。

我之所以說類是語法糖,是因?yàn)楸M管表面來看,類看起來非常面向?qū)ο?,如果做一些超過領(lǐng)域可能性范圍的事,如定義一種涉及另外兩種類的類(這是目前不可能實(shí)現(xiàn)的事),需要使用如下代碼:

  1. //Thehelper function  
  2.         functionapplyMixins(derivedCtor,baseCtors) {  
  3.             baseCtors.forEach(baseCtor => {  
  4.                 Object.getOwnPropertyNames(baseCtor.prototype).forEach(name=> {  
  5.                     let descriptor =Object.getOwnPropertyDescriptor(baseCtor.prototype, name)  
  6.                     Object.defineProperty(derivedCtor.prototype, name, descriptor);  
  7.                 });  
  8.             });  
  9.         }  
  10.         //The parent classes  
  11.         classA {  
  12.                methodA(){  
  13.                 console.log("A")  
  14.             }  
  15.         }  
  16.         classB {  
  17.             methodB(){  
  18.                 console.log("B")  
  19.             }  
  20.         }  
  21.         //The child class  
  22.         classC {  
  23.         }  
  24.         //Using mixins  
  25.         applyMixins(C, [A, B])  
  26.         let o =newC()  
  27.         o.methodA()  
  28.         o.methodB()  

我們需要做這個(gè),因?yàn)闊o法編輯JS:

  1. classA {  
  2.             methodA(){  
  3.              console.log("A")  
  4.          }  
  5.      }  
  6.         classB {  
  7.             methodB(){  
  8.              console.log("B")  
  9.          }  
  10.      }  
  11.         classCextendsA, B {  
  12.         }  

在某些情況下,這種行為可能會(huì)派上用場(chǎng),JavaScript的員工創(chuàng)建了上面的代碼片段,我只是刪除了額外的代碼,使它適用于普通JS。

但是樣本代碼的重要信息應(yīng)該是applyMixins功能。即使不充分理解它的功能,也能發(fā)現(xiàn),它用于評(píng)估各種類的原型屬性以復(fù)制和重分配方法和屬性。這是發(fā)現(xiàn)事實(shí)的全部證據(jù):類只不過是在經(jīng)過驗(yàn)證的原型繼承模型之上的語法糖。

這說明應(yīng)該停止用類嗎?并不是。理解它很重要,如果需要突破類能做和不能做的界限,將不得不處理原型來實(shí)現(xiàn)這一點(diǎn)。

JavaScript的OOP 模型錯(cuò)過了什么?

如果現(xiàn)在的OOP模型不夠完美,只是原型繼承的抽象體,那么我們錯(cuò)過了什么?什么使JS成為真正的OOP?

要解答這個(gè)問題,就先要看看JavaScript的功能,語言背后的團(tuán)隊(duì)肯定要發(fā)明能把JavaScript轉(zhuǎn)換成JS的東西,來把JavaScript推到極限。這反過來也會(huì)限制它們的功能,但是,開始OOP愿望列表的一個(gè)好方法是查看它們與OOP相關(guān)的特性。

你馬上會(huì)注意到一個(gè)警告:目前JavaScript中缺失的一些OOP構(gòu)造具有內(nèi)在的類型檢查功能,在動(dòng)態(tài)類型語言中沒有真正的意義,這可能是因?yàn)樗鼈冞€沒有被添加。

接口

這些是很好的結(jié)構(gòu),有助于定義類應(yīng)該遵循的API。接口在無類型JS中可能會(huì)丟失,它的一個(gè)主要好處是,你可以為任何實(shí)現(xiàn)相同接口的類定義一個(gè)變量,并安全地調(diào)用它的任何方法。

  1. interfaceAnimal {  
  2.            speak()  
  3.          }  
  4.         classDog implements Animal{  
  5.            speak() {  
  6.              console.log("Woof!")  
  7.            }  
  8.          }  
  9.         classCat implements Animal{  
  10.            speak() {  
  11.              console.log("Meau!")  
  12.            }  
  13.          }  
  14.         classHuman implements Animal{  
  15.            speak() {  
  16.              console.log("Hey dude, what's up?")  
  17.            }  
  18.          }  
  19.         //if we had Interfaces in JS we could safely do:  
  20.          let objects = [newDog(), newCat(), newHuman()]  
  21.          objects.forEach(o => o.speak())  

這在普通JS中是無法做到的。當(dāng)然可以通過定義speak方法并覆蓋它的類來實(shí)現(xiàn)同樣的目的。但話又說回來,也可以在任何其他強(qiáng)OOP語言中這樣做,接口更加清晰和簡(jiǎn)潔。

抽象類

每當(dāng)我嘗試用代碼進(jìn)行全OOP時(shí),肯定會(huì)錯(cuò)過JS中的抽象類。抽象類定義并實(shí)現(xiàn)方法,但永遠(yuǎn)不會(huì)被實(shí)例化。它是一種對(duì)可以擴(kuò)展但不能直接使用的常見行為進(jìn)行分組的方法。它絕對(duì)可以在當(dāng)前的JS領(lǐng)域內(nèi)實(shí)現(xiàn),而不會(huì)造成太多的破壞。

靜態(tài)多態(tài)

靜態(tài)多態(tài)允許我們?cè)谕粋€(gè)類中多次定義相同的方法,但是使用不同的簽名。換句話說,重復(fù)名稱,但要確保它接收到不同的參數(shù)?,F(xiàn)在我們使用JS有了rest參數(shù),這允許我們有任意數(shù)字,然而,這也意味著必須向方法中添加額外的代碼來處理這個(gè)層次的動(dòng)態(tài)。

相反,如果可以更清楚地區(qū)分方法簽名,那么可以直接將相同行為的不同風(fēng)格封裝到不同的方法中。

JavaScript的類出現(xiàn)了什么問題?
JavaScript的類出現(xiàn)了什么問題?

上邊版是無效的JS,但它的代碼更干凈,因此需要來進(jìn)行心理分析的認(rèn)知負(fù)荷也更少。然而,下邊版完全有效。它需要一些思維復(fù)合,周圍有更多的代碼,因?yàn)樗粌H記錄日志(這應(yīng)該是它的唯一目的),而且還試圖根據(jù)提供的參數(shù)決定如何記錄日志。

靜態(tài)多態(tài)性通常通過查看方法中接收的參數(shù)類型來實(shí)現(xiàn)。然而,由于JS的工作方式,我們知道這是不可能的。

受保護(hù)的屬性和方法

已經(jīng)有了公開的可見性,而且很快就得到了方法和屬性的私有可見性。下一步應(yīng)該是添加受保護(hù)的可見性,如果你想要有一個(gè)合適的OOP體驗(yàn),這三者都是必要的。受保護(hù)的屬性和方法只能從類內(nèi)部或它的一個(gè)子類中訪問(與私有可見性相反,私有可見性將訪問限制為只能訪問父類)。

我一直在努力把JS稱為OOP語言,直到我看到一種不用引用原型鏈就能處理類內(nèi)部的方法,我才會(huì)繼續(xù)努力下去。為什么他們不能繼續(xù)擴(kuò)展原型繼承模型,而不是給我們這個(gè)便宜的類版本呢?這是一個(gè)由來已久的問題。

現(xiàn)在,我要對(duì)添加的語法糖說聲謝謝,也會(huì)繼續(xù)關(guān)注未來的新的基于oop的特性。

 

 

責(zé)任編輯:華軒 來源: 讀芯術(shù)
相關(guān)推薦

2021-02-08 08:04:52

JavaScript語言OOP

2012-07-30 09:49:44

云計(jì)算

2014-09-28 10:28:59

Docker云計(jì)算

2011-11-30 15:28:32

在線協(xié)作系統(tǒng)

2012-08-07 09:37:23

虛擬化

2022-05-05 08:00:00

團(tuán)隊(duì)敏捷流程

2023-05-31 07:32:37

2022-06-13 10:07:13

物聯(lián)網(wǎng)開發(fā)物聯(lián)網(wǎng)

2020-06-15 08:06:25

ES數(shù)據(jù)

2020-11-02 13:25:45

Redis數(shù)據(jù)庫開源

2023-11-08 14:03:47

數(shù)據(jù)可視化數(shù)字化轉(zhuǎn)型

2024-12-09 09:30:00

適配器模式設(shè)計(jì)模式代碼

2023-10-27 13:31:18

線程安全多線程

2024-11-05 08:16:04

HTTP/3HTTP 2.0QUIC

2021-12-15 23:42:56

Webpack原理實(shí)踐

2021-07-13 07:52:03

ReactHooks組件

2019-04-26 13:01:16

ServiceMesh微服務(wù)架構(gòu)

2025-01-10 09:13:36

2020-06-12 09:40:32

消息隊(duì)列Java線程

2021-07-29 07:55:20

React Fiber架構(gòu)引擎
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)