nicholaswmin
nicholaswmin

Reputation: 22939

Dynamically add a constructor

Is there any way to dynamically add a constructor to a Class without altering the original Class itself?

I'm using a library where I instantiate objects like so:

var path = new Path()

What I want to do is something like this:

// obviously won't work but you get the point
Path.prototype.constructor = function() {
  console.log(this, 'was created')
}

var path = new Path()

I can obviously use a Factory to create my objects and in that Factory I can add a custom function and trigger it. That won't work since the library I'm using won't be using that factory internally.

Upvotes: 1

Views: 165

Answers (1)

Patrick Roberts
Patrick Roberts

Reputation: 51756

Yes, you can, but the variable Path needs to be non-const in order for it to work. This approach will require you to still call the original constructor:

Path = class extends Path {
  constructor () {
    super()
    console.log(this, 'was created')
  }
}

class Path {
  constructor () {
    console.log('old constructor')
  }
  
  foo () {
    console.log('bar')
  }
}

Path = class extends Path {
  constructor () {
    super()
    console.log(this, 'was created')
  }
}

let path = new Path()
path.foo()

You can also replace Path with a new class identical to the original except for the constructor:

Path = (Path => {
  return Object.setPrototypeOf(
    Object.setOwnPropertyDescriptors(function () {
      console.log(this, 'was created')
    }, Object.getOwnPropertyDescriptors(Path)),
    Object.getPrototypeOf(Path)
  )
})(Path)

class Path {
  constructor () {
    console.log('old constructor')
  }

  foo () {
    console.log('bar')
  }
}

Path = (Path => {
  return Object.setPrototypeOf(
    Object.defineProperties(function () {
      console.log(this, 'was created')
    }, Object.getOwnPropertyDescriptors(Path)),
    Object.getPrototypeOf(Path)
  )
})(Path)

let path = new Path()
path.foo()

Upvotes: 1

Related Questions