JS composition/inheritance prototype

136 Views Asked by At

I wish to be able to extend any object given in an .extend(obj) function. So far I have it working except for when an object literal is being passed in.

example:

class myClass {
  static extend(obj) {
    Object.assign(Object.getPrototypeOf(obj), myClass.prototype);
    myClass.call(obj);
  }

  sayHello() {
    return 'hello!'
  }
}

This works fine when the extend function is called from within a constructor like so:

function foo() {
  myClass.extend(this);
}
const bar = new foo();
bar.sayHello();

However when I pass in an object literal which is already created the methods from myClass.prototype are not available.

const foo = {};
myClass.extend(foo);
foo.sayHello(); // this is not available.

Is there a way to check the last case and assign the prototype to the object itself instead of it's prototype so that the last scenario will also work?

static extend() {
  if (/* obj is an object literal */) {
    Object.assign(obj, myClass.prototype);
  } else {
    // first example
}
1

There are 1 best solutions below

0
On

This works fine when the extend function is called from within a constructor like so:

It shouldn't work fine, and when I ran it I got the error Class constructor myClass cannot be invoked without 'new'. That error is because of the statement myClass.call(obj);. Only if I change the class to an ES5 constructor function does it work.

However when I pass in an object literal which is already created the methods from myClass.prototype are not available.

They were for me.

function myClass() {}

myClass.extend = function(obj) {
  Object.assign(Object.getPrototypeOf(obj), myClass.prototype);
  myClass.call(obj);
}

myClass.prototype.sayHello = function() {
  return 'hello!'
}

const foo = {};
myClass.extend(foo);
foo.sayHello(); // "hello!"