问题
I want to merge 2 classes or add all methods from 1 class to another. In the future It will be the more classes than just a (ContainerClient) class.
Client
and ContainerClient
I tried this but I think It can be done even easier.
for (var a of Object.getOwnPropertyNames(ContainerClient.prototype)) {
Client.prototype[a] = ContainerClient.prototype[a];
}
Principle: ContainerClient
depends on Client
Data.js
class Data {
constructor () {
}
}
Client.js
class Client extends Data {
me () {
return {
id: '1',
};
}
}
Container.js
class Container extends Data {
containers () {
return [
{
clientId: '1',
id: '2',
},
{
clientId: '2',
id: '3',
},
];
}
}
ContainerClient.js
class ContainerClient extends Data {
containers () {
return {
clientId: '1',
id: '2',
};
}
}
--> Client.js before export
<--
// --> HERE <--
for (var a of Object.getOwnPropertyNames(ContainerClient.prototype)) {
Client.prototype[a] = ContainerClient.prototype[a];
}
// -> [ 'constructor', 'me', 'containers' ] 👍
console.log(Object.getOwnPropertyNames(Client.prototype));
index.js
const client = new Client();
const container = new Container();
// -> { clientId: '1', id: '2' } 👍
console.log(client.containers());
回答1:
First the short answer: What you're doing is (almost) the best you can do. For a tiny improvement, you could replace the for loop with Object.assign and that would shorten it up by a line, but it'll still do the same thing.
Now the long answer.
I'll open by saying that I agree with a lot of the comments that this design smells (as in code smell). Most likely there should be no inheritance, and each type should be using instances of the others. Clients should use data objects. Containers should be an array of client objects. And so forth.
With that disclaimer, here's the more direct answer to your question.
The name of what you're looking for is multiple inheritance / mixins. Python, just for a quick example, natively supports multiple inheritance, so in Python you'd be able to write:
class Client(Data, ContainerClient):
...
But JavaScript's prototype chain supports only single inheritance, so you'll have to settle for some kind of workaround. One such workaround creates subclasses on the fly with a variable base. Something like:
const ClientMixin = Sup => class extends Sup {
// ...
};
const ContainerMixin = Sup => class extends Sup {
// ...
};
Then you can define your concrete classes like this:
class Container extends ContainerMixin(Data) {
// ...
}
class ContainerClient extends ClientMixin(ContainerMixin(Data)) {
// ...
}
Whether this seems easier than what you were already doing is up to you. Because the other workaround, of course, is to simply copy properties from one class to another like you were doing.
来源:https://stackoverflow.com/questions/50347811/merging-2-classes