繁体   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