Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I dynamically convert an instance of one class to another in javascript?

The question is already answered for python: Can I dynamically convert an instance of one class to another?

But I was curious if this would be possible in Javascript with ES6/ ES2015.

class A { ... }
class B extends A { ... }
class C extends A { ... }

let test = new B();

// ... After a while I want to have an instance of C instead of B in test.

Is this possible? Or is it a bad idea?

like image 908
yeouuu Avatar asked Oct 19 '25 16:10

yeouuu


1 Answers

You would have to write a method for this or replace the prototype (which can be considered a Very Bad Idea). However, you can largely treat an instance of B as if it were C by controlling this and calling the methods directly.

Since JavaScript is duck-typed and has no strong types, the traditional conversion (type casting, usually) is mostly meaningless. All state and behavior is attached to the instance and its prototype (even during runtime) rather than the compiler's understanding of the type.

You can call any of the methods from C on test using:

C.prototype.methodName.call(test, arg1, arg2);

The call method on a function invokes the function with a specified this, so you can call a method on a totally unrelated object (and it will work, so long as they share a contract).

You can always declare a copy constructor to turn B into C, using:

class C extends A {
  static fromB(other: B): C {
    return new C(B.foo, B.bar);
  }
}

(using Flow/Typescript type annotations for clarity)

Finally, and my least favorite, is claiming that test is actually an instance of C after the fact by mucking with the prototype:

Object.setPrototypeOf(test, C);

setPrototypeOf will replace test's reference to B with a reference to C and any methods on C.prototype will be accessible via test, like the explicit C.prototype call above but without needing to specify a this and using .call.

You could also go for the simple option of moving any shared methods to A and avoid this problem altogether, probably, but these are the JS equivalents of a cast.

like image 65
ssube Avatar answered Oct 21 '25 04:10

ssube