I want to use EcmaScript 6 (via Browserify and Babelify) in a new project, but it depends on third party libraries written in ES5. The problem is creating subclasses in my project which extend from the ones in libraries.
E.g:
// Library written in ES5
function Creature(type) {
this.type = type;
}
// my code in ES6
class Fish extends Creature {
constructor(name) {
super("fish");
this.name = name;
}
}
This almost works except that Creature() constructor is not run. I devised a workaround/hack which constructs the parent class's object first and then appends stuff to it:
class Fish extends Creature {
constructor(name) {
super("throw away"); //have to have this or it wont compile
let obj = new Creature("fish");
obj.name = name;
return obj;
}
}
This approach seems to work as long as the original class does not have "constructor" function.
My question is: is that the best way of extending them when using ES6's classes (save from asking the library's author to migrate)? Or is there an even better way? I would like to keep using class {} syntax in my project.
Now in ES5, there is no extends that can extend all your the properties, no constructor for initialization or super to call the constructor of the base class.
The extends keyword can be used to subclass custom classes as well as built-in objects. Any constructor that can be called with new (which means it must have the prototype property) can be the candidate for the parent class. The prototype of the ParentClass must be an Object or null .
In the ES5 version, there are no classes; a function is used to make an object directly.
In ES5, both function and return keywords are used to define a function. An arrow function is a new feature introduced in ES6 by which we don't require the function keyword to define the function.
Your solution works properly using babel. Your code gets compiled to the following ES5 code.
// Library written in ES5
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }
function Creature(type) {
this.type = type;
}
// my code in ES6
var Fish = (function (_Creature) {
function Fish(name) {
_classCallCheck(this, Fish);
_Creature.call(this, "fish");
this.name = name;
}
_inherits(Fish, _Creature);
return Fish;
})(Creature);
As you can see from the above code, the constructor of the Creature
class is called correctly. Line _Creature.call(this, "fish");
.
Babel link
I added the following code to demonstrate that fish is an instance of Creature
as well as an instance of Fish
.
var fish = new Fish("test");
console.log(fish.type);
console.log(fish.name);
console.log( fish instanceof Creature );
console.log( fish instanceof Fish);
Output:
fish
test
true
true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With