91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

如何理解JavaScript的Mixin模式

發布時間:2021-09-30 11:27:42 來源:億速云 閱讀:138 作者:柒染 欄目:web開發

本篇文章為大家展示了如何理解JavaScript的Mixin模式,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

 在 JavaScript 中,我們只能繼承單個對象。每個對象只能有一個 [[Prototype]]。并且每個類只可以擴展另外一個類。

但是有些時候這種設定(譯注:單繼承)會讓人感到受限制。例如,我有一個 StreetSweeper類和一個 Bicycle 類,現在想要一個它們的  mixin:StreetSweepingBicycle 類。

或者,我們有一個 User 類和一個 EventEmitter 類來實現事件生成(event generation),并且我們想將  EventEmitter 的功能添加到 User 中,以便我們的用戶可以觸發事件(emit event)。

有一個概念可以幫助我們,叫做 “mixins”。

根據維基百科的定義,mixin 是一個包含可被其他類使用而無需繼承的方法的類。

換句話說,mixin 提供了實現特定行為的方法,但是我們不單獨使用它,而是使用它來將這些行為添加到其他類中。

一、一個 Mixin 實例

在 JavaScript 中構造一個 mixin  最簡單的方式就是構造一個擁有實用方法的對象,以便我們可以輕松地將這些實用的方法合并到任何類的原型中。

例如,這個名為 sayHiMixin 的 mixin 用于給 User 添加一些“語言功能”:

// mixin let sayHiMixin = {   sayHi() {     alert(`Hello ${this.name}`);   },   sayBye() {     alert(`Bye ${this.name}`);   } };  // 用法: class User {   constructor(name) {     this.name = name;   } }  // 拷貝方法 Object.assign(User.prototype, sayHiMixin);  // 現在 User 可以打招呼了 new User("Dude").sayHi(); // Hello Dude!

這里沒有繼承,只有一個簡單的方法拷貝。所以 User 可以從另一個類繼承,還可以包括 mixin 來 "mix-in“ 其它方法,就像這樣 :

class User extends Person {   // ... }  Object.assign(User.prototype, sayHiMixin);

Mixin 可以在自己內部使用繼承。

例如,這里的 sayHiMixin 繼承自 sayMixin:

let sayMixin = {   say(phrase) {     alert(phrase);   } };  let sayHiMixin = {   __proto__: sayMixin, // (或者,我們可以在這兒使用 Object.create 來設置原型)    sayHi() {     // 調用父類方法     super.say(`Hello ${this.name}`); // (*)   },   sayBye() {     super.say(`Bye ${this.name}`); // (*)   } };  class User {   constructor(name) {     this.name = name;   } }  // 拷貝方法 Object.assign(User.prototype, sayHiMixin);  // 現在 User 可以打招呼了 new User("Dude").sayHi(); // Hello Dude!

請注意,在 sayHiMixin 內部對父類方法 super.say() 的調用(在標有 (*) 的行)會在 mixin 的原型中查找方法,而不是在  class 中查找。

這是示意圖(請參見圖中右側部分):

如何理解JavaScript的Mixin模式

這是因為方法 sayHi 和 sayBye 最初是在 sayHiMixin 中創建的。因此,即使復制了它們,但是它們的 [[HomeObject]]  內部屬性仍引用的是 sayHiMixin,如上圖所示。

當 super 在 [[HomeObject]].[[Prototype]] 中尋找父方法時,意味著它搜索的是  sayHiMixin.[[Prototype]],而不是 User.[[Prototype]]。

二、EventMixin

現在讓我們為實際運用構造一個 mixin。

例如,許多瀏覽器對象的一個重要功能是它們可以生成事件。事件是向任何有需要的人“廣播信息”的好方法。因此,讓我們構造一個  mixin,使我們能夠輕松地將與事件相關的函數添加到任意 class/object 中。

  • Mixin 將提供 .trigger(name, [...data]) 方法,以在發生重要的事情時“生成一個事件”。name  參數(arguments)是事件的名稱,[...data] 是可選的帶有事件數據的其他參數(arguments)。

  • 此外還有 .on(name, handler) 方法,它為具有給定名稱的事件添加了 handler 函數作為監聽器(listener)。當具有給定  name 的事件觸發時將調用該方法,并從 .trigger 調用中獲取參數(arguments)。

  • ……還有 .off(name, handler) 方法,它會刪除 handler 監聽器(listener)。

添加完 mixin 后,對象 user 將能夠在訪客登錄時生成事件 "login"。另一個對象,例如 calendar  可能希望監聽此類事件以便為登錄的人加載日歷。

或者,當一個菜單項被選中時,menu 可以生成 "select" 事件,其他對象可以分配處理程序以對該事件作出反應。諸如此類。

下面是代碼:

  1. let eventMixin = { 

  2.   /** 

  3.    * 訂閱事件,用法: 

  4.    *  menu.on('select', function(item) { ... } 

  5.   */ 

  6.   on(eventName, handler) { 

  7.     if (!this._eventHandlers) this._eventHandlers = {}; 

  8.     if (!this._eventHandlers[eventName]) { 

  9.       this._eventHandlers[eventName] = []; 

  10.     } 

  11.     this._eventHandlers[eventName].push(handler); 

  12.   }, 

  13.  

  14.   /** 

  15.    * 取消訂閱,用法: 

  16.    *  menu.off('select', handler) 

  17.    */ 

  18.   off(eventName, handler) { 

  19.     let handlers = this._eventHandlers?.[eventName]; 

  20.     if (!handlers) return; 

  21.     for (let i = 0; i < handlers.length; i++) { 

  22.       if (handlers[i] === handler) { 

  23.         handlers.splice(i--, 1); 

  24.       } 

  25.     } 

  26.   }, 

  27.  

  28.   /** 

  29.    * 生成具有給定名稱和數據的事件 

  30.    *  this.trigger('select', data1, data2); 

  31.    */ 

  32.   trigger(eventName, ...args) { 

  33.     if (!this._eventHandlers?.[eventName]) { 

  34.       return; // 該事件名稱沒有對應的事件處理程序(handler) 

  35.     } 

  36.  

  37.     // 調用事件處理程序(handler) 

  38.     this._eventHandlers[eventName].forEach(handler => handler.apply(this, args)); 

  39.   } 

  40. }; 


  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. .on(eventName, handler) &mdash; 指定函數 handler  以在具有對應名稱的事件發生時運行。從技術上講,這兒有一個用于存儲每個事件名稱對應的處理程序(handler)的 _eventHandlers  屬性,在這兒該屬性就會將剛剛指定的這個 handler 添加到列表中。

  3. .off(eventName, handler) &mdash; 從處理程序列表中刪除指定的函數。

  4. .trigger(eventName, ...args) &mdash; 生成事件:所有 _eventHandlers[eventName]  中的事件處理程序(handler)都被調用,并且 ...args 會被作為參數傳遞給它們。

用法:

// 創建一個 class class Menu {   choose(value) {     this.trigger("select", value);   } } // 添加帶有事件相關方法的 mixin Object.assign(Menu.prototype, eventMixin);  let menu = new Menu();  // 添加一個事件處理程序(handler),在被選擇時被調用: menu.on("select", value => alert(`Value selected: ${value}`));  // 觸發事件 => 運行上述的事件處理程序(handler)并顯示: // 被選中的值:123 menu.choose("123");

現在,如果我們希望任何代碼對菜單選擇作出反應,我們可以使用 menu.on(...) 進行監聽。

使用 eventMixin 可以輕松地將此類行為添加到我們想要的多個類中,并且不會影響繼承鏈。

三、總結

Mixin &mdash; 是一個通用的面向對象編程術語:一個包含其他類的方法的類。

一些其它編程語言允許多重繼承。JavaScript 不支持多重繼承,但是可以通過將方法拷貝到原型中來實現 mixin。

我們可以使用 mixin 作為一種通過添加多種行為來擴充類的方法。

如果 Mixins 意外覆蓋了現有類的方法,那么它們可能會成為一個沖突點。因此,通常應該仔細考慮 mixin  的命名方法,以最大程度地降低發生這種沖突的可能性。

上述內容就是如何理解JavaScript的Mixin模式,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

昭苏县| 海口市| 凤山市| 吴旗县| 台北市| 凌云县| 张家口市| 饶平县| 木兰县| 周至县| 砀山县| 贵德县| 长沙县| 聂拉木县| 延寿县| 福州市| 盐亭县| 司法| 濮阳市| 武威市| 甘谷县| 镇坪县| 德格县| 中西区| 澄江县| 迭部县| 焦作市| 孙吴县| 道真| 大安市| 通渭县| 定西市| 济宁市| 西昌市| 英山县| 蓝田县| 句容市| 金溪县| 耿马| 富裕县| 文山县|