我只是想讨论 Babel.js 如何将类转换为 ES5 Javascript。
Babel 使用了很多辅助函数,或者我会说“只需查看转译结果”。 :-)
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
允许我们定义:
- 构造函数(通过
class
and constructor
)
- 构造函数的
prototype
对象的原型(通过extends
)
- 放在构造函数上的方法
prototype
object
- 放置在构造函数本身上的方法(
static
)
- 一种简洁且可移植地引用基“类”构造函数及其原型信息的方法
So this:
// 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
成为构造函数
- All non-
constructor
, non-static
方法成为原型方法
-
static
方法被分配给构造函数上的属性
- 属性只是像往常一样的属性
- 创建要放置的对象
prototype
派生构造函数的属性是通过Object.create(Base.prototype)
, not new Base()
.
-
constructor
调用基本构造函数作为其第一个操作。
- 致电
super
ES5 版本中的方法(Base.prototype.baseMethod.call(this);
) 很麻烦而且容易出错,这是新语法的优点之一
一些提案将显着延长class
syntax:
- 类公共实例字段和私有实例字段
- 私有实例方法和访问器
- 静态类字段和私有静态方法
截至 2021 年 1 月,V8(Chrome、Chromium、Brave、Node.js 等中的 JavaScript 引擎)支持上述所有内容。 SpiderMonkey(在 Firefox 和其他浏览器中)和 JavaScriptCore(在 Safari 中)也紧随其后。