目錄
鑰匙要點
結論
> JavaScript中的“原型”是什麼?在JavaScript中如何使用它在繼承中?此屬性是對另一個對象的原型對象的引用。創建函數時,其原型對像也會通過函數的原型屬性創建並鏈接。當使用構造函數函數創建對象時,它從其構造函數的原型中繼承了屬性和方法。
javaScript不直接支持多個繼承。但是,可以使用混合蛋白間接實現它。混合蛋白是一種涉及將屬性從一個對象複製到另一個對象的技術。這允許對像從多個來源繼承屬性和方法。
>
首頁 web前端 js教程 JavaScript ES2015中對象繼承的模式

JavaScript ES2015中對象繼承的模式

Feb 16, 2025 am 11:38 AM

JavaScript ES2015中對象繼承的模式

鑰匙要點

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

想像我們正在建立一個玩家生活在動物世界中的遊戲。有些是朋友,有些是敵對的(像我這樣的狗人可能會說所有貓都是敵對的生物)。我們可以創建一個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>
登入後複製
登入後複製
多個繼承遭受鑽石問題(其中兩個父類定義相同的方法)。某些語言通過實施其他策略(例如)來避免此問題。 混合素是僅包含方法的小類。 Mixin並沒有擴展這些課程,而是將Mixins包含在另一個類中。例如,在PHP中,使用特徵實現Mixin。

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>
登入後複製
登入後複製
>另一種方法是編寫一個實用程序函數,該函數在定義後驗證類。可以在等待時找到一個例子,JavaScript確實支持多個繼承!由Andrea Giammarchi。請參閱“基本對象”部分。

>探索應用多種繼承和混合素的各種方法的時間。以下所有檢查的策略均可在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>
登入後複製
登入後複製
pros

    混合蛋白不能初始化
  • >
cons

需要額外的代碼
  • object.assign()有點晦澀
  • 與ES2015類合作的重塑原型繼承
  • 在構造函數中編寫對象
  • >
>使用ES2015類,您可以通過在構造函數中返回對象來覆蓋實例:

>我們可以利用該功能從子類內部的多個類中構成對象。請注意,object.sign(...)仍然與Mixin類無法正常工作,因此我在這裡也使用了對象:>

<span>class Foo {}
</span><span>console.log(typeof Foo); // "function"
</span>
登入後複製
登入後複製
因為這是指在上下文中的類(使用不可算的方法),所以object.shassign(...,this)不復制cat的方法。相反,您必須在此上明確設置此字段和方法,以便object.Assign()能夠應用這些字段和方法,例如:

>

<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語言中識別的模式。 >

您是否要在項目中使用上述兩種方法?您找到了更好的方法嗎?在評論中讓我知道!

>

>本文是由傑夫·莫特(Jeff Mott),斯科特·莫利納里(Scott Molinari),維爾丹·蘇菲奇(Vildan Softic)和瓊·元(Joan Yin )進行了審查。感謝SitePoint所有的同行評審器製作SitePoint內容的最佳功能!

javaScript ES2015對象繼承經常詢問問題 >在JavaScript中的經典和原型繼承之間有什麼區別?一個類定義一個對象的藍圖,對像是類的實例。繼承是通過從超類創建子類來實現的。另一方面,JavaScript使用原型繼承,其中對象直接從其他對象繼承。這是更靈活的,因為可以在運行時擴展或動態更改對象。

>

>'超級'關鍵字在JavaScript ES2015中如何工作?在對象的父上調用功能。當在構造函數中使用時,“超級”關鍵字單獨出現,必須在使用“此”關鍵字之前使用。 “超級”關鍵字也可用於在方法中的父對像上調用函數。 >

> JavaScript中的“原型”是什麼?在JavaScript中如何使用它在繼承中?此屬性是對另一個對象的原型對象的引用。創建函數時,其原型對像也會通過函數的原型屬性創建並鏈接。當使用構造函數函數創建對象時,它從其構造函數的原型中繼承了屬性和方法。

> javaScript如何處理多個繼承?

javaScript不直接支持多個繼承。但是,可以使用混合蛋白間接實現它。混合蛋白是一種涉及將屬性從一個對象複製到另一個對象的技術。這允許對像從多個來源繼承屬性和方法。

>

> javaScript ES2015中的'構造函數是什麼?在javascript ES2015中如何使用它?用於創建和初始化類中的對象的特殊方法。在繼承的上下文中,子類構造函數必須使用“超級”關鍵字調用超級類構造函數,然後才能使用'this'關鍵字。 >

JavaScript ES2015中的“擴展”關鍵字用於從超級類創建子類。子類繼承了超類的所有屬性和方法,但也可以添加新的屬性或覆蓋繼承的屬性。 >在JavaScript中,“類”是一種用作創建對象的藍圖的函數。它封裝了在該數據上運行的數據和功能。另一方面,“原型”是一個對象,其他對像從中繼承屬性和方法。

>

>我如何在JavaScript ES2015中的子類中覆蓋一個方法?您可以通過簡單地定義子類中具有相同名稱的方法來覆蓋子類中的方法。新方法將在子類的實例上調用。 > JavaScript中的“新”關鍵字用於創建類或構造函數函數的實例。在繼承的上下文中,“新”關鍵字用於創建一個子類的實例,該子類從超級類繼承屬性和方法。

如何在JavaScript中添加屬性? >

>在JavaScript中,您可以通過簡單地將值分配給原型對像上的屬性來將屬性添加到對象的原型中。然後,此屬性將由從構造函數函數創建的所有對象繼承。

>

以上是JavaScript ES2015中對象繼承的模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1676
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

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

JavaScript和Web:核心功能和用例 JavaScript和Web:核心功能和用例 Apr 18, 2025 am 12:19 AM

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

JavaScript在行動中:現實世界中的示例和項目 JavaScript在行動中:現實世界中的示例和項目 Apr 19, 2025 am 12:13 AM

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

了解JavaScript引擎:實施詳細信息 了解JavaScript引擎:實施詳細信息 Apr 17, 2025 am 12:05 AM

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

Python vs. JavaScript:社區,圖書館和資源 Python vs. JavaScript:社區,圖書館和資源 Apr 15, 2025 am 12:16 AM

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

Python vs. JavaScript:開發環境和工具 Python vs. JavaScript:開發環境和工具 Apr 26, 2025 am 12:09 AM

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

C/C在JavaScript口譯員和編譯器中的作用 C/C在JavaScript口譯員和編譯器中的作用 Apr 20, 2025 am 12:01 AM

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

Python vs. JavaScript:比較用例和應用程序 Python vs. JavaScript:比較用例和應用程序 Apr 21, 2025 am 12:01 AM

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

See all articles