javascript - Babel.js 如何创建将类声明编译为 ES2015?

标签 javascript class compilation babeljs

我目前的任务是将 JavaScript 组件 ES5 转换为 ES6(使用 Babel.js 编译)。在使用类和 Babel.js 之前,我们制作了原型(prototype)以从其他组件获取功能。

com.company.js.ComponentA.prototype = new com.company.js.utils.UltraFunctions()

现在当使用 Babel.js 并将 ComponentA 变成一个类时

class ComponentA {
  contructor(){
    this.property = "Proppy";
  }
  doStuff() {
    console.log("doStuff");
  }
}

当我在实例化此组件后对其进行分析时,现在发生的情况是我现在看到了两个级别的原型(prototype)。第一个原型(prototype)包含“属性”——第二个原型(prototype)嵌套在第一个原型(prototype)中,在本例中包含所有函数“doStuff”。这带来了遗留组件的问题,这些组件不应该被转换为类(还)。因为这些组件是通过二级原型(prototype)放入的,所以它们覆盖了包含由 Babel.js 编译的“合成”类的功能的原型(prototype)。

我不是在寻求解决方案。我只是想确定我对 Babel.js 将类转换为 ES5 JavaScript 的假设是否正确。尤其是如上所述创建两层原型(prototype)的事实。

更新

对不起,我误解了第一个原型(prototype)!正如@T.J.Crowder 在评论中所说,第一个是实例 - 因此“属性”被粉碎到实例中,同时通过原型(prototype)设计将功能插入“第一”级原型(prototype)。因此,将我所说的所有内容替换为二级到一级,一级到实例。

最佳答案

I just want to discuss how Babel.js converts a class to ES5 Javascript.

Babel 使用了很多辅助函数,或者我会说“看看转换后的结果”。 :-)

对于 ES2015,这是一个非常简单的映射,因为 class 语法在第一个版本中故意保持非常基本(ES2016 打算扩展它,但提案¹并没有做到这一点)他们会晚一些,可能是 ES2017 ES2018 ES2021 或 ES2022)。

class 允许我们定义:

  • 构造函数(通过classconstructor)
  • 构造函数的prototype对象的原型(prototype)(通过extends)
  • 构造函数的原型(prototype)对象的方法
  • 构造函数本身的方法(static)
  • 一种简洁、可移植地引用基“类”构造函数及其原型(prototype)信息的方法

所以这样:

// Base "class":
class Base {
    // The code for `Base` goes in this special `constructor` pseudo-method:
    constructor() {
        this.baseProp = 42;
    }

    // A method to put on the `prototype` object (an "instance method"):
    baseMethod() {
        console.log(this.baseProp);
    }

    // A method to put on the constructor (a "static method"):
    static foo() {
        console.log("This is foo");
    }
}

// Derived "class":
class Derived extends Base {
//            ^------------------ defines the prototype behind `Derived.prototype`
    // The code for `Derived`:
    constructor() {
        // Call super constructor (`Base`) to initialize `Base`'s stuff:
        super();

        // Properties to initialize when called:
        this.derivedProp = "the answer";
    }

    // Overridden instance method:
    baseMethod() {
        // Supercall to `baseMethod`:
        super.baseMethod();

        // ...
        console.log("new stuff");
    }

    // Another instance method:
    derivedMethod() {
        this.baseMethod();
        console.log(this.derivedProp);
    }
}

变成我们在 ES5 中可能写的(如果我们不使用任何辅助函数)像这样:

// This combines the name defined by `class` with the code defined in `constructor`:
var Base = function() {
    this.baseProp = 42;
};
// The "instance" method:
Base.prototype.baseMethod = function() {
    console.log(this.baseProp);
};
// The "static" method:
Base.foo = function() {
    console.log("This is foo");
};

// The derived constructor
var Derived = function() {
    // Call super constructor (`Base`) to initialize `Base`'s stuff:
    Base.call(this);

    // Properties to add when called:
    this.derivedProp = "the answer";
};

// This was done by `class` and `extends`:
Derived.prototype = Object.create(Base.prototype);
Derived.prototype.constructor = Derived;

// Overridden instance method:
Derived.prototype.baseMethod = function() {
    // Supercall to `baseMethod`:
    Base.prototype.baseMethod.call(this);

    // ...
    console.log(this.derivedProp);
};

// Another instance method:
Derived.prototype.derivedMethod = function() {
    this.baseMethod();
    console.log(this.derivedProp);
};

以上注意事项:

  • constructor 成为构造函数
  • 所有非构造函数、非static方法都成为原型(prototype)方法
  • static 方法被分配给构造函数的属性
  • 属性只是普通的属性
  • 创建要放在派生构造函数的 prototype 属性上的对象是通过 Object.create(Base.prototype) 完成的,不是 新的 Base()
  • constructor 调用基本构造函数作为其第一个操作。
  • 在 ES5 版本中调用 super 的方法 (Base.prototype.baseMethod.call(this);) 是麻烦且容易出错的,其中之一新语法的伟大之处

¹ 一些将显着扩展 class 语法的提议:

截至 2021 年 1 月,V8(Chrome、Chromium、Brave、Node.js 等中的 JavaScript 引擎)支持以上所有内容。 SpiderMonkey(在 Firefox 和其他软件中)和 JavaScriptCore(在 Safari 中)也不甘落后。

关于javascript - Babel.js 如何创建将类声明编译为 ES2015?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35774928/

相关文章:

javascript - Canvas 旋转 - JavaScript

java - 将变量从外部类传递到内部类的最佳方法

使用Makefile : how to do it right for several programs?进行编译

c++ - 在没有文件的情况下编译 C++ 代码

javascript - 如果 popper.js 无法加载则回退

AJAX 提交前的 JavaScript 验证

c++ - 访问放在类中的对象的方法

python - 在辅助方法中将 self 作为参数传递

c - 链接器错误 : what could be going on?

javascript - jquery ui selectmenu 滚动条不工作