日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

JS中的Minix和装饰器实现

發布時間:2023/12/13 综合教程 33 生活家
生活随笔 收集整理的這篇文章主要介紹了 JS中的Minix和装饰器实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Minix和裝飾器

Mixin

Mixin 是面向對象語言中一種常用的設計模式,通常稱之為組合,在js中通常使用一個中間的繼承對象實現。

A對象有功能a,C對象需要繼承自A對象并添加x功能,

解決辦法1:我們可以使用C繼承自A,再在C上定義x功能。但是如果D類型需要繼承自B類型,同樣也需要該x功能,我們就只能重寫一遍功能。

解決方法2:將x功能進行封裝到一個Mixin函數中,Mixin函數接受類型A作為參數,然后在這個Mixin函數中創建一個新的類型Temp,Temp繼承A并添加該x功能。這樣C只需要繼承這個新建的Temp就可以同時擁有A和x功能了。這種方式將類型A作為參數。同樣的,如果B類型的子類想添加這個x功能,只需要將B作為參數傳入這個Mixin函數,然后繼承這個函數的返回值。

代碼簡單實現

class A {                // 普通類型A,他只能打印它的x屬性,無法打印y和z屬性
    constructor(x, y, z){
        this.x = x
        this.y = y
        this.z = z
        this.showX = () => {console.log(this.x)}
    }
}

function MixinShowY (SupCls){  // 可以打印y屬性功能的函數,接受一個類型為參數
    class Tempcls extends SupCls{
        constructor(...args){
            super(...args)
            this.showY = () => {console.log(this.y)}
        }
    } 
    return Tempcls    // 返回值為一個類 
}

class C extends MixinShowY(A){}  
// MixinShowB(A) 的返回值為一個類,可以被C繼承,繼承后同時擁有MixinShowB和A的功能

在MixinShowB函數中,接受一個類作為參數來創建一個新的類型并添加功能showB,任何一個類型都可以被傳入,然后返回新的類型并添加功能。便實現了這個函數功能的復用。

Mixin疊加
上面中z屬性無法被打印,我們可以繼續定義Minix函數添加這個功能

function MixinShowZ (SupCls){  // 增加可以打印y屬性功能的函數,接受一個類型為參數
    class Tempcls extends SupCls{
        constructor(...args){
            super(...args)
            this.showZ = () => {console.log(this.Z)}
        } 
    }
    return Tempcls    // 返回值為一個類 
}

class D extends MixinShowY(C){}
// 或者
class D extends MixinShowZ(MixinShowZ(A)){}

obj = new D(1,2,3)
obj.showX()
obj.showY()

上面的兩種寫法效果相同,第二種在A的基礎上連續使用兩次包裝Mixin。獲得了ShowY和ShowZ兩個功能;

此時如果想定義一個類B,他需要在A的基礎上增加ShowZ方法,而不需要ShowY,只需要

class B extends MixinShowZ(A){}

需要哪種功能,就使用該功能對應的Mixin函數混入即可。

裝飾器

裝飾器語法在ES7中的定義,它是一個語法糖,依賴于ES5的Object.defineProperty方法,由于是ES7中的語法,需要使用babel將代碼轉譯為ES5以前的,可以在babel官網在線轉譯少量代碼,也可以在本機上搭建離線的轉譯環境。可以查看博主的JS模塊化管理及babel離線環境搭建

裝飾器,顧名思義就是可以為一個對象添加某種功能的包裝器,在目前JS中只有使用class定義的類才能使用裝飾器

繼續上面的示例,我們為A類添加一個ShowY的功能

function addShowY(cls){  // 裝飾器函數
    class Temp extends cls{
        constructor(...args){
            super(...args)
            this.showY = () => {console.log(this.y)}
        }
    }
    return Temp
}

@addShowY  // 等價于 A = addshowY(A),裝飾后A標識符已經指向了addShowY的返回值,一個新的類
class A {
    constructor(x, y, z){
        this.x = x
        this.y = y
        this.z = z
        this.showX = () => {console.log(this.x)}
    }
}

a = new A(1,2,3)
a.showY()    // 調用成功

任何需要這個功能類,都可以使用這個裝飾器進行裝飾

@addShowY
class B{
    constructor(a, b, c, d){
        this.a = a
        this.b = b
        this.c = c
        this.d = d
    }
}

帶參裝飾器

我們還可以使用帶參數的裝飾器,這需要對象裝飾器函數進行些許的改變,想象一下這個帶參裝飾器函數未來的使用方式應該是下面這樣。

@addname("root")   // 為類添加一個family屬性,這個family可以自己指定。等價于C = addname(root)(C)
class C(){}        // 這樣C 類將會擁有一個指定的famliy屬性

從用法樂意看出,這個addname函數將會被調用,調用后的返回值是一個接受類的函數,然后返回值為一個類,即

function addname(family){
    
    function func(cls){     // 
        class Temp extends cls{
            constructor(...args){
                super(...args)
                this.family = family
            }
        }
        return Temp  // func()函數調用,返回新的類
    }
    return func    // addname調用后返回一個函數,這個函數執行 func(cls)
}

@addname("root")
class C(){
    constructor(x,y){
        this.x = x
        this.y = y
    }
}

let obj = new C(1,2)

console.log(obj.family)

同樣的,這個裝飾器可以用于任何類,并且很久傳入的參數不同,類中被裝飾的屬性值不同,通過這種技術,我們可以將一些通用的功能抽象到一個裝飾器函數中,對需要使用該功能類使用裝飾器注入功能,從而避免了反復的在不同的類中實現相同的代碼,從而然代碼更加簡潔可讀。

總結

以上是生活随笔為你收集整理的JS中的Minix和装饰器实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。