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 pile
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.
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 pile
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.
Your solution works properly using babel. Your code gets piled 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
ES5 constructors and ES6 classes can live seamlessly in an inheritance chain. If you transpile your code, before running, into ES5 using tools like Babel, you can see it all translates to Prototype based inheritance. Please look at this example here which has both classes and constructor functions in three levels of inheritance chain. Hope this helps.