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

JavaScript中的類(lèi)有什么問(wèn)題?

開(kāi)發(fā) 前端
并不是說(shuō) JS 的類(lèi)有問(wèn)題,但是如果你使用該語(yǔ)言已有一段時(shí)間,特別是使用過(guò)ES5,那么你可能就知道了從原型繼承到當(dāng)前類(lèi)模型的演變。

[[381342]]

本文已經(jīng)過(guò)原作者 Fernando Doglio 授權(quán)翻譯。

并不是說(shuō) JS 的類(lèi)有問(wèn)題,但是如果你使用該語(yǔ)言已有一段時(shí)間,特別是使用過(guò)ES5,那么你可能就知道了從原型繼承到當(dāng)前類(lèi)模型的演變。

原型鏈會(huì)有什么問(wèn)題?

以我的拙見(jiàn),這個(gè)問(wèn)題的答案是:沒(méi)有。但是社區(qū)花了很多年的時(shí)間才將類(lèi)的概念強(qiáng)加到不同的結(jié)構(gòu)和庫(kù)中,因此ECMA技術(shù)委員會(huì)決定無(wú)論如何都要添加它。

你會(huì)問(wèn),這有什么問(wèn)題嗎?這就是他們真正做的,在我們已經(jīng)擁有的原型繼承之上添加了一些構(gòu)成,并決定將其稱(chēng)為類(lèi),這反過(guò)來(lái)又讓開(kāi)發(fā)人員認(rèn)為他們正在處理一種面向?qū)ο蟮恼Z(yǔ)言,而實(shí)際上它們并不是。

類(lèi)只不過(guò)是語(yǔ)法糖

jS 沒(méi)有完全的 OOP 支持,它從來(lái)沒(méi)有,這是因?yàn)樗鼜膩?lái)都不需要它。

表面上,當(dāng)前版本的類(lèi)顯示OOP范例,因?yàn)椋?/p>

  • 我們可以創(chuàng)建基本的類(lèi)定義,用非常經(jīng)典的語(yǔ)法將狀態(tài)和行為分組在一起。
  • 我們可以從一個(gè)類(lèi)繼承到另一個(gè)類(lèi)。
  • 我們可以在公有和私有之間定義屬性和方法的可見(jiàn)性(盡管私有字段仍然是一個(gè)實(shí)驗(yàn)性的特性)。
  • 我們可以為屬性定義getter和setter。
  • 我們可以實(shí)例化類(lèi)。

那么為什么我說(shuō)類(lèi)是語(yǔ)法糖呢?因?yàn)楸M管在表面上,它們看起來(lái)是非常面向?qū)ο蟮?,但是如果我們?cè)噲D做一些超出它們可能的事情,比如定義一個(gè)類(lèi)擴(kuò)展兩個(gè)類(lèi)(目前不可能的事情),我們需要使用下面的代碼

  1. // 輔助函數(shù) 
  2. function applyMixins(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. class A { 
  11.   methodA () { 
  12.     console.log('A'
  13.   } 
  14.  
  15. class B { 
  16.   methodB () { 
  17.     console.log('B'
  18.   } 
  19.  
  20. class C { 
  21.  
  22.  
  23. // 使用 mixins 

我們需要這樣做,因?yàn)樵贘S中我們無(wú)法編寫(xiě):

  1. class A { 
  2.  
  3.     methodA(){ 
  4.         console.log("A"
  5.     } 
  6.  
  7. class B { 
  8.  
  9.     methodB(){ 
  10.         console.log("B"
  11.     } 
  12.  
  13. class C extends A, B { 
  14.  

在上面的示例中,關(guān)鍵部分應(yīng)該是applyMixins函數(shù)。如果,你沒(méi)有完全理解它試圖做什么,但可以清楚地看到它正在訪(fǎng)問(wèn)所有類(lèi)的原型屬性來(lái)復(fù)制和重新分配方法和屬性。這就是我們需要看到真相的地方:類(lèi)只不過(guò)是在經(jīng)過(guò)驗(yàn)證的原型繼承模型之上的語(yǔ)法糖。

這是否意味著我們應(yīng)該停止使用類(lèi)?當(dāng)然不是,重要的是要理解它,而且如果我們想做些突破類(lèi)的限制,那么我們就必須用原型來(lái)處理。

JS 的OOP 模型缺失了什么呢?

如果我們當(dāng)前的OOP模型是如此之薄,僅是原型繼承的抽象層,那么我們到底缺少什么呢?是什么讓JS真正成為OOP?

看這個(gè)問(wèn)題的一個(gè)好方法就是看看TypeScript在做什么。該語(yǔ)言背后的團(tuán)隊(duì)通過(guò)創(chuàng)建一些可以翻譯成JS的東西,無(wú)疑將 JS 推向了極限。這反過(guò)來(lái)也限制了它們的能力。

目前 JS 中缺失的一些OOP構(gòu)造具有內(nèi)在的類(lèi)型檢查功能,在動(dòng)態(tài)類(lèi)型語(yǔ)言中沒(méi)有真正的意義,這可能是它們還沒(méi)有被添加的原因。

接口

接口可幫助定義類(lèi)應(yīng)遵循的API。接口的主要好處之一是,我們可以定義實(shí)現(xiàn)相同接口的任何類(lèi)的變量,然后安全地調(diào)用其任何方法。

  1. interface Animal { 
  2.   speak() 
  3.  
  4. class Dog implements Animal{ 
  5.   speak() { 
  6.     console.log("Woof!"
  7.   } 
  8.  
  9. class Cat implements Animal{ 
  10.   speak() { 
  11.     console.log("Meau!"
  12.   } 
  13.  
  14. class Human implements Animal{ 
  15.   speak() { 
  16.     console.log("Hey dude, what's up?"
  17.   } 
  18.  
  19. //如果我們?cè)贘S中有接口,我們可以放心地做: 
  20. let objects = [new Dog(), new Cat(), new Human()] 
  21. objects.forEach(o => o.speak()) 

當(dāng)然,我們可以通過(guò)定義speak方法并覆蓋它的類(lèi)來(lái)實(shí)現(xiàn)同樣的目的,但接口更加清晰和優(yōu)雅。

抽象類(lèi)

每當(dāng)我嘗試對(duì)我的代碼進(jìn)行完整的OOP操作時(shí),我肯定會(huì)錯(cuò)過(guò)JS中的抽象類(lèi)。抽象類(lèi)是定義和實(shí)現(xiàn)方法的類(lèi),但永遠(yuǎn)不會(huì)實(shí)例化。這是一種可以擴(kuò)展但從未直接使用的常見(jiàn)行為的分組方式。這是一個(gè)很好的資源,并且絕對(duì)可以在當(dāng)前JS領(lǐng)域內(nèi)實(shí)現(xiàn)而不會(huì)花費(fèi)太多精力。

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

靜態(tài)多態(tài)性使我們可以在相同的類(lèi)中多次定義相同的方法,但是具有不同的簽名。換句話(huà)說(shuō),重復(fù)該名稱(chēng),但要確保其接收不同的參數(shù)?,F(xiàn)在我們有了JS的rest參數(shù),這使我們可以擁有一個(gè)任意數(shù)字,但是,這也意味著我們必須在方法中添加額外的代碼來(lái)處理這種動(dòng)態(tài)性。相反,我們可以更清楚地區(qū)分方法簽名,則可以將相同行為的不同含義直接封裝到不同方法中。

左邊的版本不是有效的JS,但它提供了一個(gè)更干凈的代碼,因此,閱讀和理解起來(lái)比較容易。右邊的版本是完全有效的,它閱讀起來(lái)相對(duì)困難些,還要懂得一些 ES6 的語(yǔ)法。

多態(tài)性通常是通過(guò)查看方法中接收到的參數(shù)的類(lèi)型來(lái)實(shí)現(xiàn)的。但是,由于JS的工作原理,我們知道這是不可能的。

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

我們已經(jīng)有了公開(kāi)的可見(jiàn)性,而且我們很快就得到了方法和屬性的私有可見(jiàn)性(通過(guò)#前綴)。我認(rèn)為下一步應(yīng)該是添加受保護(hù)的可見(jiàn)性,然而,現(xiàn)在還沒(méi)有,我認(rèn)為如果你想要有一個(gè)合適的OOP體驗(yàn),這三個(gè)都是必要的。受保護(hù)的屬性和方法只能從類(lèi)內(nèi)部或它的一個(gè)子類(lèi)中訪(fǎng)問(wèn)(與私有可見(jiàn)性相反,私有可見(jiàn)性將訪(fǎng)問(wèn)限制為只能訪(fǎng)問(wèn)父類(lèi))。

今天就跟大家分享到這里了,我是小智,我們下期再見(jiàn)。

作者:Fernando Doglio 譯者:前端小智 來(lái)源:meidum

原文:https://blog.bitsrc.io/whats-wrong-with-javascript-s-classes-3378c73205af

本文轉(zhuǎn)載自微信公眾號(hào)「大遷世界」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系大遷世界公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 大遷世界
相關(guān)推薦

2021-03-23 18:32:46

JavaScript編程開(kāi)發(fā)

2024-12-13 09:26:35

2020-06-15 08:06:25

ES數(shù)據(jù)

2023-05-12 07:35:43

ChatGPT代碼字符串

2012-09-19 09:45:16

移動(dòng)互聯(lián)網(wǎng)廣告模式

2019-04-26 13:01:16

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

2022-12-07 10:34:15

智能家居Matter

2022-04-04 07:51:32

Web框架

2012-07-30 09:49:44

云計(jì)算

2021-07-16 06:56:50

邊緣計(jì)算分布式

2020-05-22 10:02:43

Python語(yǔ)言編程

2021-10-16 12:52:17

Builder模式生成器

2024-09-12 09:34:32

2014-09-28 10:28:59

Docker云計(jì)算

2022-06-29 07:49:42

云存儲(chǔ)架構(gòu)DevOps

2024-12-27 15:28:01

CQRS架構(gòu)方式

2023-05-31 07:32:37

2011-11-30 15:28:32

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

2020-08-02 23:20:36

JavaScriptmap()forEach()

2023-07-21 17:08:30

點(diǎn)贊
收藏

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