[英]In which way can i pass through a method call in JavaScript class
Assume we have some classes A and B:假设我们有一些 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!');
};
};
Then we create an instance of B like this:然后我们像这样创建一个 B 的实例:
const objB = new B(
new A(3)
);
So now we have objB with its own method inside - printText, and we surely can call it.所以现在我们有了objB,里面有它自己的方法——printText,我们当然可以调用它。 But what if i want somehow when calling not existing method in objB to make it pass through to encapsulated A class in there and look for invoking this method on him, like this:
objB.showInfo()
- to give me 3
here ?但是,如果我想在调用 objB 中不存在的方法时以某种方式使其传递到那里的封装 A 类并寻找在他身上调用此方法,例如:
objB.showInfo()
- 在这里给我3
怎么办?
Same story, but at this time i want when calling not existing method on A to make it pass through to B outside (like that printText
)?同样的故事,但是此时我想在 A 上调用不存在的方法以使其通过外部 B (例如
printText
)?
PS Don't wanna use super()
and inheritance, just composition and wrapping objects, hope you've got the point. PS 不想使用
super()
和继承,只是组合和包装对象,希望你明白这一点。
Just a little warning at the start: this might make your program harder to debug, and it also might be a little complicated for something like this.一开始只是一个小警告:这可能会使您的程序更难调试,并且对于这样的事情也可能有点复杂。 As others have suggested, you should probably investigate other options which may be simpler and also less in the way of everything else your code does.
正如其他人所建议的那样,您可能应该研究其他可能更简单且对您的代码所做的所有其他事情的方式也更少的选项。
Here's the code which provides the functionality:这是提供功能的代码:
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;
}
}
});
}
And one itty bitty change to your constructor in B
:并对
B
中的构造函数进行了一点小小的更改:
class B {
constructor(b) {
this.b = b;
return makeGetProxy(this);
};
printText() {
console.log('its B!');
};
};
If you want, you can also do the same to A
.如果你愿意,你也可以对
A
做同样的事情。
Let's slow down.让我们放慢速度。 What just happened?
刚才发生了什么? I'll explain.
我会解释的。
Since the properties we might request don't already exist, we're going to have to use a getter (see resources) to properly send back the value required.由于我们可能请求的属性尚不存在,因此我们将不得不使用 getter(请参阅参考资料)正确地发回所需的值。 But, since we don't know the property names, we need a
Proxy
(see resources) to have a "catch-all" kind of get
method.但是,由于我们不知道属性名称,我们需要一个
Proxy
(请参阅参考资料)来拥有一种“包罗万象”的get
方法。
The proxy will check if the property requested prop
already exists, and if so, returns it.代理将检查属性请求的
prop
是否已经存在,如果存在,则返回它。 If it doesn't exist, it checks all of your properties' properties (all of the sub-properties).如果它不存在,它会检查所有属性的属性(所有子属性)。
The first result it gets, it returns it.它得到的第一个结果,它返回它。 This might cause unexpected bugs in your program.
这可能会导致程序中出现意外错误。 If it doesn't find it, it simply returns
undefined
.如果它没有找到它,它只会返回
undefined
。
Then, the proxy is generalized into a function for reuse in multiple classes (as you requested).然后,代理被泛化为一个函数,以便在多个类中重用(根据您的要求)。
So, this can get the properties of a class and the properties of a class' properties, but if you need to go further (with your C
class that doesn't exist yet), you can use a recursive function.所以,这可以得到一个类的属性和一个类的属性,但是如果你需要更进一步(你的
C
类还不存在),你可以使用递归函数。 I currently don't have the implementation for that recursive function, but in my head it would comprise mostly of a modified version of the else
block in the makeGetProxy
function.我目前没有该递归函数的实现,但在我的脑海中,它主要包含
makeGetProxy
函数中else
块的修改版本。
Again, be careful with this code.同样,要小心这段代码。 It might get in the way of other things and cause unnecessary difficulty in debugging.
它可能会妨碍其他事情并在调试中造成不必要的困难。
Resources:资源:
Proxy
idea from this answer .Proxy
的想法。This is one way you can do it.这是您可以做到的一种方式。 It's pretty clunky (having to reference
B.prototype
, which JS class syntax generally does a good job of hiding from you), and using setPrototypeOf is not recommended as the warning on that docs page shows - but if you really need to have instances of B dynamically delegate whatever object is held in the b
property, then this should do the trick.它非常笨重(必须引用
B.prototype
,JS 类语法通常可以很好地隐藏你),并且不建议使用 setPrototypeOf ,因为该文档页面上显示的警告 - 但如果你真的需要实例B 动态委托b
属性中保存的任何对象,那么这应该可以解决问题。
But I encourage you to rethink your architecture if you really find yourself needing this pattern!但如果你真的发现自己需要这种模式,我鼓励你重新考虑你的架构!
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.