簡體   English   中英

我可以通過哪種方式通過 JavaScript 類中的方法調用

[英]In which way can i pass through a method call in JavaScript class

假設我們有一些 A 類和 B 類:

Class A {
    constructor(a) {
       this.a = a;
    };
    showInfo() {
        console.log(this.a)
    };
};

Class B {
    constructor(b) {
        this.b = b;
    };
    printText() {
        console.log('its B!');
    };
};

然后我們像這樣創建一個 B 的實例:

const objB = new B(
    new A(3)
);
  1. 所以現在我們有了objB,里面有它自己的方法——printText,我們當然可以調用它。 但是,如果我想在調用 objB 中不存在的方法時以某種方式使其傳遞到那里的封裝 A 類並尋找在他身上調用此方法,例如: objB.showInfo() - 在這里給我3怎么辦?

  2. 同樣的故事,但是此時我想在 A 上調用不存在的方法以使其通過外部 B (例如printText )?

PS 不想使用super()和繼承,只是組合和包裝對象,希望你明白這一點。

一開始只是一個小警告:這可能會使您的程序更難調試,並且對於這樣的事情也可能有點復雜。 正如其他人所建議的那樣,您可能應該研究其他可能更簡單且對您的代碼所做的所有其他事情的方式也更少的選項。

這是提供功能的代碼:

function makeGetProxy(t){
    return new Proxy(t, {
        get(obj,prop){
            if(prop in t){
                return t[prop];
            }else{
                var keys = Object.keys(obj);
                for (var i = 0; i < keys.length; i++) {
                    var val = t[keys[i]];
                    if(prop in val){
                        return val[prop];
                        // what about a recursive function?
                    }
                }
                return undefined;
            }
        }
    });
}

並對B中的構造函數進行了一點小小的更改:

class B {
    constructor(b) {
        this.b = b;
        return makeGetProxy(this);
    };
    printText() {
        console.log('its B!');
    };
};

如果你願意,你也可以對A做同樣的事情。

讓我們放慢速度。 剛才發生了什么? 我會解釋的。

  1. 由於我們可能請求的屬性尚不存在,因此我們將不得不使用 getter(請參閱參考資料)正確地發回所需的值。 但是,由於我們不知道屬性名稱,我們需要一個Proxy (請參閱參考資料)來擁有一種“包羅萬象”的get方法。

  2. 代理將檢查屬性請求的prop是否已經存在,如果存在,則返回它。 如果它不存在,它會檢查所有屬性的屬性(所有子屬性)。

  3. 它得到的第一個結果,它返回它。 這可能會導致程序中出現意外錯誤。 如果它沒有找到它,它只會返回undefined

  4. 然后,代理被泛化為一個函數,以便在多個類中重用(根據您的要求)。

所以,這可以得到一個類的屬性一個類的屬性,但是如果你需要更進一步(你的C類還不存在),你可以使用遞歸函數。 我目前沒有該遞歸函數的實現,但在我的腦海中,它主要包含makeGetProxy函數中else塊的修改版本。

同樣,要小心這段代碼。 它可能會妨礙其他事情並在調試中造成不必要的困難。

資源:

這是您可以做到的一種方式。 它非常笨重(必須引用B.prototype ,JS 類語法通常可以很好地隱藏你),並且不建議使用 setPrototypeOf ,因為該文檔頁面上顯示的警告 - 但如果你真的需要實例B 動態委托b屬性中保存的任何對象,那么這應該可以解決問題。

但如果你真的發現自己需要這種模式,我鼓勵你重新考慮你的架構!

 class A { constructor(a) { this.a = a; }; showInfo() { console.log(this.a) }; }; class B { constructor(b) { this.b = b; Object.setPrototypeOf(B.prototype, this.b); }; printText() { console.log('its B!'); }; }; const objB = new B( new A(3) ); objB.printText(); objB.showInfo();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM