javascript - Extending EcmaScript 5 classes in ES6 code - Stack Overflow

admin2025-04-22  0

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.

Share Improve this question asked May 25, 2015 at 21:31 ArnelismArnelism 1,5141 gold badge15 silver badges22 bronze badges 2
  • 1 Babel relies on the ES5 classes properly setting 'Creature.prototype.constructor = Creature `, perhaps you aren't doing that properly? If the parent class is the absolute base, that should happen automatically, but if the parent class has its own parent, it's possible it has the wrong '.constructor'. – loganfsmyth Commented May 26, 2015 at 2:15
  • 1 The example code you posted works correctly unpiled in both browsers and Node.js. If it wasn't working when transpiled it must have been due to a bug in one of your transpilers. – cpcallen Commented Sep 10, 2022 at 17:43
Add a ment  | 

2 Answers 2

Reset to default 3

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.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745268976a293457.html

最新回复(0)