0

I would like to convert a function that return multiple functions, into a class with a constructor that should be called only with the new keyword.

I tried this :

const toast = () => {
  return ({
    getToast: () => {
      return 'toast'
    },
    setToast: () => {
      return 'wtf'
    }
  })
}

class t {
  constructor() {}
}

const t1 = t.bind(toast())
const tt = new t1()
console.log(tt.getToast)

But it print undefined.

I also tried Object.assign(t, toast()), or doing simply this = toast() in the constructor but it doesn't work.

tfontain
  • 66
  • 12
  • 1
    Why are you trying to do that? What problem are you trying to solve? Why do you need a class? If you just want to be able to call `toast` with `new` then declaring it as a normal function instead would be the simplest solution. If you can't do that then `function t() { return toast(); }` would work. – Felix Kling Oct 18 '20 at 22:34
  • Does this answer your question? [Convert JavaScript function to class with callback methods](https://stackoverflow.com/questions/58032695/convert-javascript-function-to-class-with-callback-methods) – Randy Casburn Oct 18 '20 at 22:35
  • you may need to consider the difference between functions and arrow functions too – Jaromanda X Oct 18 '20 at 22:36
  • @FelixKling Thanks for your answer, but you can still call the function without `new`, right ? @RandyCasburn It doesn't really help me, no. – tfontain Oct 18 '20 at 22:45
  • 2
    Yes. You can do `class t { constructor() { return toast(); } }` as well if you really only want a *constructable* function. Though I still don't understand why this limitation is necessary. – Felix Kling Oct 18 '20 at 22:48
  • `Object.assign(t.prototype, toast())` might be what you're looking for (assuming the `toast()` takes no arguments and has no state). But really you probably should just rewrite your code and declare those methods in the `class t` itself? – Bergi Oct 18 '20 at 23:06

2 Answers2

0

I do not know what are you trying to do. May be you are looking for this.

const toast = () => {
  return ({
    getToast: () => {
      return 'toast'
    },
    setToast: () => {
      return 'wtf'
    }
  })
}

class t {
  constructor(fn) {
    return fn;
  }
}

const tt = new t(toast())
console.log(tt.getToast())
console.log(tt.setToast())
mr hr
  • 3,162
  • 2
  • 9
  • 19
0

For your exact scenario, that is if the function returns an object with only functions and no non-function properties, one way to do this is simply using prototype inheritance:

function t () {}; // though by convention a class should REALLY be uppercase

t.prototype = toast();

Now you can do:

let bread = new t();
let bagel = new t();

bread.getToast();
bagel.getToast();

You can also use a design pattern called parasitic inheritance but this is less memory efficient because just like the toast() function it creates a copy of the functions for each object:

class t {
    constructor () {
        let tmp = toast();
        
        // Copy methods to our instance:
        for (let prop in tmp) {
            this[prop] = tmp[prop];
        }
    }
}

Or with Object.assign() it would simply be:

class t {
    constructor () {
        Object.assign(this, toast());
    }
}

However, as mentioned, the prototype inheritance is the better mechanism for this use-case.

slebetman
  • 109,858
  • 19
  • 140
  • 171