问题
Here is the thing. I have a main class called A. I want this class to extend class B.
class A extends B {}
But in fact, I want the class B to extend C, D or E on a specific condition:
class B extends B1 {}
or
class B extends B2 {}
or
class B extends B3 {}
So the B class would be a "fake" class, just to check a condition and then extend the right class. In the final, the result would be the same as:
class A extends B1 {}
or
class A extends B2 {}
or
class A extends B3 {}
I know this is possible in PHP, with abstract classes or wrapper classes for example. But how to do that in JavaScript ES6?
Thanks
回答1:
So classes in javascript are really not setup in the same classical inheritance way as other languages, the best way to do what you want is to set the prototype of the object you are dealing with. There are a few ways.
Object.setPrototypeOf(currentObj, newPrototype);
Where newPrototype is the object you are wanting to inherit from. Here are a couple good articles on it if you want to learn the inner workings.
http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/
https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md
回答2:
Weird, but possible:
class subClassFirst {
report() {
console.log(`Extended ${this.name} from the first class`);
}
}
class subClassSecond {
report() {
console.log(`Extended ${this.name} from the second class`);
}
}
class subClassThird {
report() {
console.log(`Extended ${this.name} from the third class`);
}
}
function classCreator(condition) {
let sub;
switch (condition) {
case 'first':
sub = subClassFirst;
break;
case 'second':
sub = subClassSecond;
break;
case 'third':
sub = subClassThird;
break;
}
return (class extends sub {
constructor(name) {
super();
this.name = name;
}
});
}
let myClass;
myClass = classCreator('first');
let mcf = new myClass('f');
myClass = classCreator('second');
let mcs = new myClass('s');
myClass = classCreator('third');
let mct = new myClass('t');
mcf.report();
mcs.report();
mct.report();
回答3:
There's a Node JS function for that
const util = require("util");
class MySubClass {}
class MySuperClass {}
util.inherits(MySubClass, MySuperClass);
回答4:
I found blog post that gave an easy es6 way that doesn't use util.inherits
https://www.mikedoesweb.com/2017/dynamic-super-classes-extends-in-es6/
Here is how I used a passed option to determine which class to extend and then obfuscated that in the export
import ClassB from ' '
import ClassA form ' '
const ext = {
classA: ClassA, // the default
classB: ClassB
// can do as many as you want
}
function ExtendsMyClass (opts= {}) {
if (!new.target) {
throw new Error('Uncaught TypeError: Class constructor Interrupt cannot be invoked without \'new\'')
}
// one could vet opts here too including opts.extend
class MyClass extends ext[opts.extend || 'classA'] {
constructor(opts = {}) {
super(opts)
....
}
} // end MyClass
return new MyClass(opts)
} // end dynamic extend
export default ExtendsMyClass
export { ExtendsMyClass as MyClass }
I'll probably make this into "wrapper" utility function that accepts also the child class as well. That way one can dynamically extend any class as opposed to the one off implementation above. Could even implement dynamic imports if it was set up an async function.
来源:https://stackoverflow.com/questions/42599560/javascript-class-extend-on-condition