I have three classes, two of them extending the third. Is it possible to somehow (different than manually) assign extending classes' names to the super constructor?
class Master {
constructor(options) {
this.methods = Object.getOwnPropertyNames( Master.prototype );
}
getMethods() {
return Object.getOwnPropertyNames( Master.prototype );
}
}
class SlaveOne extends Master {
constructor(options) {
super(options);
}
methodOne() {}
methodTwo() {}
}
class SlaveTwo extends Master {
constructor(options) {
super(options);
}
methodThree() {}
methodFour() {}
}
So, what I want is to have either method or this.methods assignment in the Master class, which will:
return ['constructor', 'methodOne', 'methodTwo'] when called on an instance of SlaveOne;
return ['constructor', 'methodThree', 'methodFour'] when called on an instance of SlaveTwo;
My current code will return same ['constructor', 'getMethods'] when called either on instance of SlaveOne, SlaveTwo or Master. Any ideas?
Something like this should do the trick
class Master {
getMethods() {
return Object.getOwnPropertyNames( this.constructor.prototype );
}
}
class SlaveOne extends Master {
constructor(options) {
super(options);
}
methodOne() {}
methodTwo() {}
}
class SlaveTwo extends Master {
constructor(options) {
super(options);
}
methodThree() {}
methodFour() {}
}
console.log(new SlaveOne().getMethods(), new SlaveTwo().getMethods())
Related
I am working on a "main" class that should extend either our v1 or v2 implementation based on user passed options i.e.
User initiates this "main" class via something like
new MainClass({ version: 1});
Under the hood MainClass looks something like this
class MainClass extends MainClassV1 {
constructor(options: { version: 1 | 2 }) {
super()
}
}
Is it possible to tweak this so that this main class extends MainClassV2 if user provides version: 2?
I don't think you can literally do that, no. But you can have a factory function that returns one instance type or the other based on the options you feed it. Here's a quick sketch:
class MainClassCommon {
// ...stuff that MainClassV1 and MainClassV2 have in common...
constructor(options: CreateMainClassCommonOptions) {
// ...
}
}
class MainClassV1 extends MainClassCommon {
constructor(options: CreateMainClassOptionsV1) {
super(options);
// ...
}
// ...v1 stuff...
}
class MainClassV2 extends MainClassCommon {
constructor(options: CreateMainClassOptionsV2) {
super(options);
// ...
}
// ...v2 stuff...
}
type CreateMainClassCommonOptions = {
someOption: string;
}
type CreateMainClassOptionsV1 = CreateMainClassCommonOptions & {
version: 1;
v1Option: number;
}
type CreateMainClassOptionsV2 = CreateMainClassCommonOptions & {
version: 2;
v2Option: string;
}
type CreateMainClassOptions =
| CreateMainClassOptionsV1
| CreateMainClassOptionsV2;
type CreateMainClassResult<Options extends CreateMainClassOptions> =
Options extends CreateMainClassOptionsV1
? MainClassV1
: MainClassV2;
function createMainClass<Options extends CreateMainClassOptions>(options: Options): CreateMainClassResult<Options> {
if (options.version === 1) {
return new MainClassV1(options);
}
return new MainClassV2(options);
}
Playground link
I have two classes in javascript a, b. Class b extends a. Class a calls method in constructor. I wanna override this method in b class. How to call overridable method? when I added to class a, to constructor this.method(), it always calls method from a class.
class a {
constructor() {
this.method();
}
method() {
alert("a");
}
}
class b extends a {
constructor() {
super();
}
method() {
alert("b");
}
}
If you don't know in advance whether the instance is of the subclass or superclass, you can make sure the superclass calls its own method by having the superclass reference itself explicitly:
A.prototype.method.call(this);
class A {
constructor() {
A.prototype.method.call(this);
}
method() {
console.log("a");
}
}
class B extends A {
constructor() {
super();
}
method() {
console.log("b");
}
}
const b = new B();
class A {
constructor(){
this.method()
}
method(){
alert("a");
}
}
class B extends A {
constructor(){
super()
}
method(){
alert("b");
}
}
new B();
Wonder if anyone can help?
I'm trying to call a parent's constructor or at a minimum get a reference to the parent class in some way without hardcoding anything.
class A {
static foo(options) {
parent::__construct(options); <- this is how you would get the parent in php
}
}
class B extends A {
}
Is this possible?
In a javascript class (and OOP in general), a static method is not part of an instance and therefore the object it resides in does not have a constructor.
You should avoid using static method for this sort of thing and use a standard constructor and call super() to call the parent constructor.
class A {
constructor(options) {
console.log('Options are:');
console.log(options);
}
}
class B extends A {
constructor(options) {
super(options);
}
}
const item = new B({item1: 'abc'});
Further reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
You can use super() to call parent constructor
class A {
constructor() {
console.log('I\'m parent ');
}
foo(){
console.log('Class A: Called foo');
}
}
class B extends A {
constructor() {
super();
}
foo(){
super.foo()
}
}
const b = new B();
b.foo();
This doesn't work. Is there a way for a child class in JS to have access to its parents static methods?
class Person {
constructor() {}
static isHuman() {
return 'yes I am';
}
}
class Brian extends Person {
constructor() {
super();
}
greeting() {
console.log(super.isHuman())
}
}
const b = new Brian();
b.greeting();
Yes you can. You can use super but to get at the static method you have to access the constructor property of it:
super.constructor.isHuman()
You can also use the class name directly:
Person.isHuman();
//this works because Brian inherits the static methods from Person
Brian.isHuman();
Or by going up the prototype chain
//would be referencing Brian
this.constructor.isHuman();
//would be referencing Person
this.__proto__.constructor.isHuman();
Object.getPrototypeOf(this).constructor.isHuman();
Demo
class Person {
constructor() {}
static isHuman() {
return 'yes I am';
}
}
class Brian extends Person {
constructor() {
super();
}
greeting() {
console.log("From super: ", super.constructor.isHuman())
console.log("From class name (Brian): ", Brian.isHuman())
console.log("From class name (Person): ", Person.isHuman())
console.log("From prototype chain: ", this.constructor.isHuman())
console.log("From prototype chain: ", Object.getPrototypeOf(this).constructor.isHuman())
}
}
const b = new Brian();
b.greeting();
For static methods, use the class name rather than super.
class Person {
constructor() {}
static isHuman() {
return 'yes I am';
}
}
class Brian extends Person {
constructor() {
super();
}
greeting() {
console.log(Person.isHuman())
}
}
const b = new Brian();
b.greeting();
I am curious can I call a extended class and have it still import the things it needs specifically.
Welcome Class:
import { ErrorLevel } from './error-level.js';
export class Welcome extends ErrorLevel {
constructor() {
super();
}
}
Error-Level Class:
import { Notification } from 'aurelia-notification';
export class ErrorLevel {
static inject() {
return [Notification];
}
constructor(notification) {
this.notification = notification;
}
}
I know once I call super() it will call the extended class and pass in 0 arguments. Is there a way for my ErrorClass constructor to pull in Notification when I call super()?
super([arguments]); // calls the parent constructor.
super.functionOnParent([arguments]);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
Passing an argument in Welcome's super function calls the parent class constructor with that argument. You will see the log of this contains notification which is set to the argument we pass into super.
http://jsbin.com/raguqopesu/1/edit?js,console,output
class ErrorLevel {
constructor(notification) {
this.notification = notification;
}
}
class Welcome extends ErrorLevel {
constructor() {
super(Notification);
console.log(this);
}
}
const yo = new Welcome();
export class Welcome extends ErrorLevel {
constructor(notification) {
super(notification);
}
}