My current mission is to convert a JavaScript component ES5 to ES6 (compiled with Babel.js). Before using classes and Babel.js we prototyped to get functions from other components.
com.company.js.ComponentA.prototype = new com.company.js.utils.UltraFunctions()
Now when using Babel.js and turning ComponentA into a class
class ComponentA {
contructor(){
this.property = "Proppy";
}
doStuff() {
console.log("doStuff");
}
}
What happens now when I analyse this Component after instantiating it is that I see two level of prototypes now. The first prototype holds "property" - the second one, which is nested into the first one holds all function in this case "doStuff". That brings up problems with legacy components which should not be converted to classes (yet). Because these components are being put in through the second level prototype they override the prototype which holds the functions of the "synthetic" class compiled by Babel.js.
I am not asking for a solution. I just want to get sure if I am right with the assumption Babel.js converts the classes to ES5 JavaScript. Especially the fact of creating two level prototypes as mentioned above.
Update
I'm sorry I miunderstood the first prototype! as @T.J.Crowder said in the comments the first is the instance - therefore "property" is being smashed into the instance while the functions are being inserted through prototyping to the "first" level prototype. So, replace everything what I said with second level to first level and first level to instance.
Babel uses a lot of helper functions, or I'd say "just look at the transpiled result." :-)
With ES2015, it's a really simple mapping, because the
class
syntax was deliberately kept really basic for this first version (ES2016 was going to extend it, but the proposals didn't quite make it so they'll be later, probably ES2017).class
allows us to define:class
andconstructor
)prototype
object's prototype (viaextends
)prototype
objectstatic
)So this:
becomes what we might write in ES5 (if we didn't use any helper functions) like this:
Items of note above:
constructor
becomes the constructor functionconstructor
, non-static
methods become prototype methodsstatic
methods are assigned to properties on the constructor functionprototype
property of a derived constructor function is done viaObject.create(Base.prototype)
, notnew Base()
.constructor
calls the base constructor as its first action.super
's methods in the ES5 version (Base.prototype.baseMethod.call(this);
) are cumbersome and error-prone, one of the great things about the new syntaxThe ES6/Babel class syntax replicates the same prototypal pattern that you would get if you were using function constructors and overwriting the prototype. The examples below will result in the same instance object once calling the constructor.
ES6/Babel
ES5
Below is an example of how to inherit the prototype of another constructor in both ES6 class syntax and in ES5.
ES6/Babel
ES5
In the example you've given, your ComponentA is not inheriting the prototype of UltraFunctions() in the same way because you are not resetting the ComponentA.prototype.constructor back to the ComponentA function after overwriting it's prototype.
The result is a ComponentA instance object which in not really an instance of ComponentA but instead it's an instance of UltraFunctions() that was mutated by the ComponentA constructor.
You may have some negative results since a number of Object.prototype methods like .hasOwnProptery are not going to work the way they used to once you migrate your components to use the class syntax.
The other issue with your example is the "constructor" is misspelled. Which will cause the result in Babel to be different than what you may be expecting.