JavaScript ES2015中對象繼承的模式
鑰匙要點
- >使用ES2015,JavaScript現在具有專門定義類的語法,以保持代碼清潔,最小化層次結構深度並避免重複代碼。 >多重繼承(由某些經典OOP語言支持的功能)允許創建從多個基類繼承的類。但是,它遇到了鑽石問題,其中兩個父類定義了相同的方法。
- 混合蛋白,僅包含方法的微小類是躲避鑽石問題的另一種策略。 Mixins不用擴展這些類,而是在另一個類中包含。 >
- >儘管班級語法給出了一種幻想,即JavaScript是一種基於類的OOP語言,但事實並非如此。大多數方法都需要修改對象的原型以模仿多重繼承。使用類工廠功能是使用Mixins組成類的可接受策略。
- JavaScript的 > ES2015(以前稱為ES6)的已久的到來,配備了專門定義類的語法。在本文中,我將探討是否可以利用類語法來撰寫較小零件的類。

想像我們正在建立一個玩家生活在動物世界中的遊戲。有些是朋友,有些是敵對的(像我這樣的狗人可能會說所有貓都是敵對的生物)。我們可以創建一個hostileanimal,它可以擴展動物,以充當貓的基礎。在某個時候,我們決定添加旨在傷害人類的機器人。我們要做的第一件事是創建機器人類。現在,我們有兩個具有相似屬性的類。例如,hostileanimal和機器人都可以攻擊()。
>
>如果我們可以以某種方式在單獨的類或對像中定義敵意,請說敵對,我們可以將其重用為CAT作為機器人。我們可以以各種方式做到這一點。
>多重繼承
是某些經典的OOP語言支持的功能。顧名思義,它使我們能夠創建一個從多個基類繼承的類。查看CAT類在以下Python代碼中如何擴展多個基類:and接口
是(鍵入)經典OOP語言中的常見功能。它允許我們定義類應包含的方法(有時是屬性)。如果該課程沒有,編譯器將引起錯誤。如果CAT沒有攻擊()或walk()方法:<span>class Animal(object): </span> <span>def walk(self): </span> <span># ... </span> <span>class Hostile(object): </span> <span>def attack(self, target): </span> <span># ... </span> <span>class Dog(Animal): </span> <span># ... </span> <span>class Cat(Animal, Hostile): </span> <span># ... </span> dave <span>= Cat(); </span>dave<span>.walk(); </span>dave<span>.attack(target); </span>
a recap:es2015類語法
>如果您沒有機會參加ES2015課程或覺得自己對它們的了解不足,請務必閱讀Jeff Mott面向對象的JavaScript - 在繼續之前深入研究ES6課程。 > 簡而言之:<span>interface Hostile { </span> <span>attack(); </span><span>} </span> <span>class Animal { </span> <span>walk(); </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal implements Hostile { </span> <span>attack() { </span> <span>// ... </span> <span>} </span><span>} </span>
>類foo {...}描述了一個名為foo
的類
類foo擴展bar {...}描述了一個foo的類,該類擴展了另一個類,bar>
在類塊中,我們可以定義該類的屬性。在本文中,我們只需要了解構造函數和方法:- 構建器(){...}是一個保留函數,在創建時執行(new foo())
- > foo(){...}創建一個名為foo 的方法
級語法主要是JavaScript原型模型上的句法糖。它不是創建類,而是創建一個函數構造函數:
>- 的要點是,JavaScript不是基於類的OOP語言。甚至可能認為語法是欺騙性的,給人的印像是。 組成ES2015類
- 可以通過創建一個拋出錯誤的虛擬方法來模仿 接口。一旦繼承,就必須覆蓋該功能以避免錯誤:
如前所述,這種方法依賴於繼承。要繼承多個類,我們將需要多個繼承或混合素。
<span>class Animal { </span> <span>// ... </span><span>} </span> <span>trait Hostile { </span> <span>// ... </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span> <span>class Robot { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span>
>探索應用多種繼承和混合素的各種方法的時間。以下所有檢查的策略均可在GitHub上獲得。
>
object.assign(childclass.protype,mixin ...)> ES2015前,我們使用原型來繼承。所有功能都有一個原型屬性。使用新的myFunction()創建實例時,將原型複製到實例中的屬性。當您嘗試訪問不在實例的屬性時,JavaScript引擎將嘗試在原型對像中查找。
進行演示,請查看以下代碼:<span>class Foo {} </span><span>console.log(typeof Foo); // "function" </span>
可以在運行時創建和修改這些原型對象。最初,我試圖將課程用於動物和敵對:
<span>class Animal(object): </span> <span>def walk(self): </span> <span># ... </span> <span>class Hostile(object): </span> <span>def attack(self, target): </span> <span># ... </span> <span>class Dog(Animal): </span> <span># ... </span> <span>class Cat(Animal, Hostile): </span> <span># ... </span> dave <span>= Cat(); </span>dave<span>.walk(); </span>dave<span>.attack(target); </span>
上面的方法是不起作用的,因為類方法是>不枚舉的。實際上,這意味著對象。分配(...)不從類複製方法。這也使得很難創建一個將方法從一個類複製到另一個類的函數。但是,我們可以手動複製每種方法:
><span>interface Hostile { </span> <span>attack(); </span><span>} </span> <span>class Animal { </span> <span>walk(); </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal implements Hostile { </span> <span>attack() { </span> <span>// ... </span> <span>} </span><span>} </span>
>另一種方法是拋棄類並使用對像作為混合物。積極的副作用是Mixin對像不能用於創建實例,以防止濫用。
<span>class Animal { </span> <span>// ... </span><span>} </span> <span>trait Hostile { </span> <span>// ... </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span> <span>class Robot { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span>
- 混合蛋白不能初始化
- >
需要額外的代碼
- 行
- object.assign()有點晦澀 與ES2015類合作的重塑原型繼承
- 在構造函數中編寫對象 >
>我們可以利用該功能從子類內部的多個類中構成對象。請注意,object.sign(...)仍然與Mixin類無法正常工作,因此我在這裡也使用了對象:
<span>class Foo {} </span><span>console.log(typeof Foo); // "function" </span>
>
<span>class IAnimal { </span> <span>walk() { </span> <span>throw new Error('Not implemented'); </span> <span>} </span><span>} </span> <span>class Dog extends IAnimal { </span> <span>// ... </span><span>} </span> <span>const robbie = new Dog(); </span>robbie<span>.walk(); // Throws an error </span>
我認為我們可以同意後者更可讀。
<span>function <span>MyFunction</span> () { </span> <span>this.myOwnProperty = 1; </span><span>} </span><span>MyFunction.prototype.myProtoProperty = 2; </span> <span>const myInstance = new MyFunction(); </span> <span>// logs "1" </span><span>console.log(myInstance.myOwnProperty); </span><span>// logs "2" </span><span>console.log(myInstance.myProtoProperty); </span> <span>// logs "true", because "myOwnProperty" is a property of "myInstance" </span><span>console.log(myInstance.hasOwnProperty('myOwnProperty')); </span><span>// logs "false", because "myProtoProperty" isn’t a property of "myInstance", but "myInstance.__proto__" </span><span>console.log(myInstance.hasOwnProperty('myProtoProperty')); </span>
pros
<span>class Animal { </span> <span>walk() { </span> <span>// ... </span> <span>} </span><span>} </span> <span>class Dog { </span> <span>// ... </span><span>} </span> <span>Object.assign(Dog.prototype, Animal.prototype); </span>
>它有效,我猜
>cons
- 非常模糊的 ES2015類語法
濫用ES2015類
- 類工廠功能
- 這種方法利用JavaScript在運行時定義類的能力。
- 首先,我們需要基礎類。在我們的例子中,動物和機器人充當基礎類別。如果您想從頭開始,一個空的班級也可以。 >
>現在,我們可以將任何類傳遞給敵對功能,該函數將返回一個新的類,結合敵對的新類,以及我們傳遞給該功能的任何類:
我們可以通過幾個類進行管道應用多個混合素:
<span>Object.assign(Cat.prototype, { </span> <span>attack: Hostile.prototype.attack, </span> <span>walk: Animal.prototype.walk, </span><span>}); </span>
pros
<span>const Animal = { </span> <span>walk() { </span> <span>// ... </span> <span>}, </span><span>}; </span> <span>const Hostile = { </span> <span>attack(target) { </span> <span>// ... </span> <span>}, </span><span>}; </span> <span>class Cat { </span> <span>// ... </span><span>} </span> <span>Object.assign(Cat.prototype, Animal, Hostile); </span>
>更容易理解,因為所有信息都在類聲明標題中
<span>class Answer { </span> <span>constructor(question) { </span> <span>return { </span> <span>answer: 42, </span> <span>}; </span> <span>} </span><span>} </span> <span>// { answer: 42 } </span><span>new Answer("Life, the universe, and everything"); </span>
cons >當我決定研究此主題並撰寫有關它的文章時,我希望JavaScript的原型模型有助於生成課程。由於類語法使方法無法恢復,因此對像操縱變得更加困難,幾乎不切實際。 類語法可能會產生幻想,即JavaScript是一種基於類的OOP語言,但事實並非如此。使用大多數方法,您將必須修改對象的原型以模仿多重繼承。使用類工廠功能的最後一種方法是使用Mixins組成類的可接受策略。
如果出於任何原因,您仍然喜歡經典的編程,則可能需要研究編譯為JavaScript的語言。例如,打字稿是JavaScript的超集,它添加了(可選的)靜態鍵入和您將從其他經典OOP語言中識別的模式。 您是否要在項目中使用上述兩種方法?您找到了更好的方法嗎?在評論中讓我知道! javaScript ES2015對象繼承經常詢問問題
>在JavaScript中的經典和原型繼承之間有什麼區別?一個類定義一個對象的藍圖,對像是類的實例。繼承是通過從超類創建子類來實現的。另一方面,JavaScript使用原型繼承,其中對象直接從其他對象繼承。這是更靈活的,因為可以在運行時擴展或動態更改對象。 > javaScript如何處理多個繼承? > javaScript ES2015中的'構造函數是什麼?在javascript ES2015中如何使用它?用於創建和初始化類中的對象的特殊方法。在繼承的上下文中,子類構造函數必須使用“超級”關鍵字調用超級類構造函數,然後才能使用'this'關鍵字。 > 如何在JavaScript中添加屬性? >
結論
>'超級'關鍵字在JavaScript ES2015中如何工作?在對象的父上調用功能。當在構造函數中使用時,“超級”關鍵字單獨出現,必須在使用“此”關鍵字之前使用。 “超級”關鍵字也可用於在方法中的父對像上調用函數。
> JavaScript中的“原型”是什麼?在JavaScript中如何使用它在繼承中?此屬性是對另一個對象的原型對象的引用。創建函數時,其原型對像也會通過函數的原型屬性創建並鏈接。當使用構造函數函數創建對象時,它從其構造函數的原型中繼承了屬性和方法。
javaScript不直接支持多個繼承。但是,可以使用混合蛋白間接實現它。混合蛋白是一種涉及將屬性從一個對象複製到另一個對象的技術。這允許對像從多個來源繼承屬性和方法。
>>
>我如何在JavaScript ES2015中的子類中覆蓋一個方法?您可以通過簡單地定義子類中具有相同名稱的方法來覆蓋子類中的方法。新方法將在子類的實例上調用。 > JavaScript中的“新”關鍵字用於創建類或構造函數函數的實例。在繼承的上下文中,“新”關鍵字用於創建一個子類的實例,該子類從超級類繼承屬性和方法。 >
以上是JavaScript ES2015中對象繼承的模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。
