溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript中的類有什么問題

發(fā)布時間:2021-08-25 06:44:45 來源:億速云 閱讀:159 作者:chen 欄目:web開發(fā)

這篇文章主要介紹“JavaScript中的類有什么問題”,在日常操作中,相信很多人在JavaScript中的類有什么問題問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JavaScript中的類有什么問題”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

并不是說 JS 的類有問題,但是如果你使用該語言已有一段時間,特別是使用過ES5,那么你可能就知道了從原型繼承到當前類模型的演變。

原型鏈會有什么問題?

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

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

類只不過是語法糖

jS 沒有完全的 OOP 支持,它從來沒有,這是因為它從來都不需要它。

表面上,當前版本的類顯示OOP范例,因為:

  • 我們可以創(chuàng)建基本的類定義,用非常經(jīng)典的語法將狀態(tài)和行為分組在一起。

  • 我們可以從一個類繼承到另一個類。

  • 我們可以在公有和私有之間定義屬性和方法的可見性(盡管私有字段仍然是一個實驗性的特性)。

  • 我們可以為屬性定義getter和setter。

  • 我們可以實例化類。

那么為什么我說類是語法糖呢?因為盡管在表面上,它們看起來是非常面向?qū)ο蟮?,但是如果我們試圖做一些超出它們可能的事情,比如定義一個類擴展兩個類(目前不可能的事情),我們需要使用下面的代碼

// 輔助函數(shù) function applyMixins(derivedCtor, baseCtors) {     baseCtors.forEach(baseCtor => {         Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {             let descriptor = Object.getOwnPropertyDescriptor(baseCtor.prototype, name)             Object.defineProperty(derivedCtor.prototype, name, descriptor);         });     }); }  class A {   methodA () {     console.log('A')   } }  class B {   methodB () {     console.log('B')   } }  class C {  }  // 使用 mixins

我們需要這樣做,因為在JS中我們無法編寫:

class A {      methodA(){         console.log("A")     } }  class B {      methodB(){         console.log("B")     } }  class C extends A, B {  }

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

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

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

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

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

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

接口

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

interface Animal {   speak() }  class Dog implements Animal{   speak() {     console.log("Woof!")   } }  class Cat implements Animal{   speak() {     console.log("Meau!")   } }  class Human implements Animal{   speak() {     console.log("Hey dude, what's up?")   } }  //如果我們在JS中有接口,我們可以放心地做: let objects = [new Dog(), new Cat(), new Human()] objects.forEach(o => o.speak())

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

抽象類

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

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

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

JavaScript中的類有什么問題

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

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

到此,關(guān)于“JavaScript中的類有什么問題”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI