简体   繁体   English

在ES6代码中扩展EcmaScript 5类

[英]Extending EcmaScript 5 classes in ES6 code

I want to use EcmaScript 6 (via Browserify and Babelify) in a new project, but it depends on third party libraries written in ES5. 我想在一个新项目中使用EcmaScript 6(通过Browserify和Babelify),但它依赖于用ES5编写的第三方库。 The problem is creating subclasses in my project which extend from the ones in libraries. 问题是在我的项目中创建子类,它从库中的子类扩展。

Eg: 例如:

// 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. 这几乎可以工作,除了没有运行Creature()构造函数。 I devised a workaround/hack which constructs the parent class's object first and then appends stuff to it: 我设计了一个解决方法/ hack,它首先构造父类的对象,然后将东西添加到它:

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)? 我的问题是:使用ES6的类是扩展它们的最佳方法(除了要求图书馆的作者迁移)? Or is there an even better way? 还是有更好的方法? I would like to keep using class {} syntax in my project. 我想在我的项目中继续使用class {}语法。

Your solution works properly using babel. 您的解决方案使用babel正常工作。 Your code gets compiled to the following ES5 code. 您的代码将编译为以下ES5代码。

// 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. 从上面的代码中可以看出,正确调用了Creature类的构造函数。 Line _Creature.call(this, "fish"); 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 . 我添加了以下代码来演示fish是Creature一个实例以及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. ES5构造函数和ES6类可以无缝地存在于继承链中。 If you transpile your code, before running, into ES5 using tools like Babel , you can see it all translates to Prototype based inheritance. 如果您在使用像Babel这样的工具运行之前将代码转换为ES5,您可以看到它全部转换为基于Prototype的继承。 Please look at this example here which has both classes and constructor functions in three levels of inheritance chain. 请查看此示例其中包含三个级别的继承链中的类和构造函数。 Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM