Home > database >  Javascript init class properties before calling super
Javascript init class properties before calling super

Time:02-20

i'm trying to convert my javascript classes from old style to new style. The problem is, that with the new style JavaScript requires that in a constructor super is called before accessing this. I have to extend a class that i am not the owner of and in that constructor it calls a method that i overwrite where i use my own properties. How to solve that?

class A {
    constructor() {
        this.create()
    }

    create() {}

    reload() {
        this.create()
    }
}

class B extends A {
    constructor(options) {
        super()
        this.options = options
    }

    create() {
        let title = this.options.title // TypeError: Cannot read properties of undefined (reading 'title')
    }
}

CodePudding user response:

I'd make the prototype's create a no-op, and then call a function after the super() is done.

class A {
    constructor() {
        this.create()
    }
    create() {}
}

class B extends A {
    constructor(options) {
        super()
        this.options = options
        this.createB();
    }

    createB() {
        const title = this.options.title;
        console.log(title);
    }
    create() {}
}

new B({ title: 'foo' });

I suppose you could also assign to .create after the super runs, turning it from a no-op back to your desired functionality.

class A {
    constructor() {
        this.create()
    }
    create() {}
}

function createB() {
}
class B extends A {
    constructor(options) {
        super()
        this.options = options
        this.create = () => {
            const title = this.options.title;
            console.log(title);
        };
        this.create();
    }
    create() {}
}

new B({ title: 'foo' });

CodePudding user response:

I would add a guard in B's create, and have its constructor execute it again:

class A {
    constructor() {
        this.create();
    }

    create() {
        console.log("I don't want to run this");
    }

    reload() {
        this.create();
    }
}

class B extends A {
    constructor(options) {
        super();
        this.options = options;
        this.create(); // ... but now
    }

    create() {
        if (!this.hasOwnProperty("options")) return; // not now...
        let title = this.options.title;
        console.log("title", title);
    }
}

let b = new B({ title: "my title" });
console.log("let's reload");
b.reload();

  • Related