Babel.js create 如何将类声明编译成 ES2015? [英] How does Babel.js create compile a class declaration into ES2015?

查看:33
本文介绍了Babel.js create 如何将类声明编译成 ES2015?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前的任务是将一个 JavaScript 组件 ES5 转换为 ES6(使用 Babel.js 编译).在使用类和 Babel.js 之前,我们设计了原型以从其他组件获取函数.

My current mission is to convert a JavaScript component ES5 to ES6 (compiled with Babel.js). Before using classes and Babel.js we prototyped to get functions from other components.

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

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

Now when using Babel.js and turning ComponentA into a class

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

当我在实例化后分析这个 Component 时会发生什么,我现在看到了两个级别的原型.第一个原型保存属性" - 第二个,嵌套在第一个原型中,在这种情况下保存所有函数doStuff".这带来了不应转换为类的遗留组件的问题(尚).因为这些组件是通过二级原型放入的,所以它们覆盖了保存 Babel.js 编译的合成"类功能的原型.

What happens now when I analyse this Component after instantiating it is that I see two level of prototypes now. The first prototype holds "property" - the second one, which is nested into the first one holds all function in this case "doStuff". That brings up problems with legacy components which should not be converted to classes (yet). Because these components are being put in through the second level prototype they override the prototype which holds the functions of the "synthetic" class compiled by Babel.js.

我不是在寻求解决方案.我只是想确定我对 Babel.js 将类转换为 ES5 JavaScript 的假设是否正确.尤其是上面提到的创建两级原型的事实.

I am not asking for a solution. I just want to get sure if I am right with the assumption Babel.js converts the classes to ES5 JavaScript. Especially the fact of creating two level prototypes as mentioned above.

对不起,我误解了第一个原型!正如@T.J.Crowder 在评论中所说的,第一个是实例——因此,属性"正在被粉碎到实例中,而函数则通过原型设计插入到第一"级原型中.所以,把我说的一切都换成二级到一级,一级到实例.

I'm sorry I miunderstood the first prototype! as @T.J.Crowder said in the comments the first is the instance - therefore "property" is being smashed into the instance while the functions are being inserted through prototyping to the "first" level prototype. So, replace everything what I said with second level to first level and first level to instance.

推荐答案

我只想讨论 Babel.js 如何将类转换为 ES5 Javascript.

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

Babel 使用了很多辅助函数,或者我会说只需查看转换后的结果".:-)

Babel uses a lot of helper functions, or I'd say "just look at the transpiled result." :-)

在 ES2015 中,这是一个非常简单的映射,因为 class 语法在第一个版本中故意保持非常基本(ES2016 将对其进行扩展,但提案¹ 并没有完全做到这一点他们会更晚,可能是 ES2017 ES2018 ES2021 或 ES2022).

With ES2015, it's a really simple mapping, because the class syntax was deliberately kept really basic for this first version (ES2016 was going to extend it, but the proposals¹ didn't quite make it so they'll be later, probably ES2017 ES2018 ES2021 or ES2022).

class 允许我们定义:

  • 构造函数(通过classconstructor)
  • 构造函数的prototype对象的原型(通过extends)
  • 放置在构造函数的prototype对象上的方法
  • 放置构造函数本身的方法(static)
  • 一种引用基类"的方法;构造函数及其原型信息简洁可移植
  • The constructor function (via class and constructor)
  • The constructor function's prototype object's prototype (via extends)
  • Methods to put on the constructor function's prototype object
  • Methods to put on the constructor function itself (static)
  • A means of referencing the base "class" constructor and its prototype information concisely and portably

所以:

// 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 中编写的内容(如果我们不使用任何辅助函数),如下所示:

becomes what we might write in ES5 (if we didn't use any helper functions) like this:

// 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 成为构造函数
  • 所有非constructor、非static方法都成为原型方法
  • static 方法被分配给构造函数上的属性
  • 属性只是像往常一样的属性
  • 通过Object.create(Base.prototype)不是来创建对象以放置在派生构造函数的prototype属性上> new Base().
  • constructor 调用基本构造函数作为它的第一个动作.
  • 在 ES5 版本中调用 super 的方法 (Base.prototype.baseMethod.call(this);) 既麻烦又容易出错,其中之一新语法的优点
  • constructor becomes the constructor function
  • All non-constructor, non-static methods become prototype methods
  • static methods are assigned to properties on the constructor function
  • Properties are just properties as usual
  • Creating the object to put on the prototype property of a derived constructor function is done via Object.create(Base.prototype), not new Base().
  • constructor calls the base constructor as its first action.
  • Calls to the super's methods in the ES5 version (Base.prototype.baseMethod.call(this);) are cumbersome and error-prone, one of the great things about the new syntax

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

¹ Some proposals that will markedly extend class syntax:

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

As of January 2021, V8 (the JavaScript engine in Chrome, Chromium, Brave, Node.js, and others) supports all of the above. SpiderMonkey (in Firefox and others) and JavaScriptCore (in Safari) aren't too far behind.

这篇关于Babel.js create 如何将类声明编译成 ES2015?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆