JavaScript - Class extend on condition

柔情痞子 提交于 2020-06-16 05:29:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!