0

Is it possible in JavaScript to create a new ES6 class instance that would have access to properties of an existing object right within the constructor?

I have an ES5 class:

function ES5() {
    this.value = 123;
}

And I need to be able to create an ES6 class instance:

class ES6 {
    constructor() {
        console.log(this.value); /* must print 123 */
    }
}

that would have access to the ES5 class properties from within the constructor.

Basically, I want something like:

Object.create(ES6.prototype, new ES5());

though I know this code doesn't work. But is there a way to make this type of logic work?


I have a library that accepts a function for creating new objects, and I have added a way to check if it is an ES6 class, to initialize it differently, with the new operand, while providing my own existing object for the class.

NOTE: This also means that class ES6 has no knowledge of the ES5 class existence, only of its properties. Or to put it otherwise, class ES6 needs to get property value automatically, it cannot patch itself.

more details

My library executes new ES5() internally, while class ES6 is declared on the client side. So they co-exist independently. And when the client passes me in the ES6 class, I need to instantiate it in such a way that it thinks it extends class ES5, i.e. has access to the extra properties.

function createClass(func) {
  if(/* func is an ES6 class*/) {
      var a = new ES5();
      return /* new ES6 instance that has access to ES5 object properties */
  } else {
      return new ES5();
  }
}
7
  • 1
    If it doesn't know anything about ES5, how could it do new ES5()? Commented Aug 24, 2018 at 22:04
  • How is the relationship between ES5 and ES6 established? Commented Aug 24, 2018 at 22:06
  • My library executes new ES5() internally, while class ES6 is declared on the client side. So they co-exist independently. And when the client passes me in the ES6 class, I need to instantiate it in such a way that it thinks it extends class ES5. Commented Aug 24, 2018 at 22:06
  • 1
    But you have to tell ES6 which class it's supposed to extend somehow. Commented Aug 24, 2018 at 22:08
  • Your example is incomplete, it just makes things worst and more vague than before. Commented Aug 24, 2018 at 22:21

1 Answer 1

1

You can set the prototype of the class to the ES5 instance. This will put the instance and the ES5 function in the prototype chain:

function ES5() {
    this.value = 123;
}

class ES6 {
    constructor() {
        console.log(this.value); /* must print 123 */
    }
}
let e5 = new ES5()

Object.setPrototypeOf(ES6.prototype, e5)
let e6 = new ES6

// ES5 now in the prototype chain of e6
console.log("instance of ES5:", e6 instanceof ES5)
console.log("instance of ES6:", e6 instanceof ES6)

// they are linked by prototype (not sure if that's good or bad for your use):
console.log("es6 value: ", e6.value)
e5.value = "newValue"
console.log("es6 value: ", e6.value)
 

Sign up to request clarification or add additional context in comments.

7 Comments

This is awesome, thank you! I would also include the older answer, like the one by ibrahim at the moment, for completeness, to cover every scenario ;)
@vitaly-t just one note though, this mutates the ES6 class itself. Any future instances of this class will be affected. Any future mutations will affect all the previous instances. Giving how createClass is defined I guess this will lead to other problems. I can't even tell if that's bad or not as I still don't understand what you are looking for.
@ibrahimmahrir yes, it is a trade off, which means I would need to call setPrototypeOf before creating any new ES6 instance, but it is still usable ;) b.t.w. I like your answer also, but I can't accept both of them :)
@vitaly-t Are you expecting only instances of the ES5 class to be passed to createClass? If not this will lead to serious problems like instance that have properties they don't use (imagine you call createClass with an instance of another EcmaScript 5 class that doesn't have the value property after you passed the class ES5 to it, the new ES6 instance will still have the value property of the previous instance). Is that ok?
@ibrahimmahrir is correct that this could be shaky. Once you create an ES6 instance, if you then change the prototype of the ES6 class, past instances will reflect this change. So running Object.setPrototypeOf(ES6.prototype, someotherinstance) would effect everything because all the old instances would now be linked to the new prototype chain.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.