@babel/plugin-transform-classes
这个插件包含在 @babel/preset-env 中
注意事项
🌐 Caveats
当扩展一个原生类(例如 class extends Array {})时,超类需要被封装。这是为了解决两个问题:
🌐 When extending a native class (e.g., class extends Array {}), the super class
needs to be wrapped. This is needed to workaround two problems:
- Babel 使用
SuperClass.apply(/* ... */)转译类,但原生类不能被调用,因此在这种情况下会报错。 - 一些内置函数(比如
Array)总是返回一个新对象。Babel 不应该直接返回它,而是应该把它当作新的this来处理。
这个封装器在 IE11 以及其他浏览器上都可以使用,Object.setPrototypeOf 或 __proto__ 作为备用方案。
不支持 IE 10 及以下版本。如果你需要支持 IE 10 及以下,建议不要扩展原生对象。
🌐 The wrapper works on IE11 and every other browser with Object.setPrototypeOf or __proto__ as fallback.
There is NO IE ≤ 10 support. If you need IE ≤ 10 it's recommended that you don't extend natives.
Babel 需要静态地知道你是否在扩展一个内置类。出于这个原因,‘混入模式’不起作用:
🌐 Babel needs to statically know if you are extending a built-in class. For this reason, the "mixin pattern" doesn't work:
class Foo extends mixin(Array) {}
function mixin(Super) {
return class extends Super {
mix() {}
};
}
要解决此限制,你可以在继承链中添加另一个类,以便 Babel 可以封装原生类:
🌐 To workaround this limitation, you can add another class in the inheritance chain so that Babel can wrap the native class:
const ExtensibleArray = class extends Array {};
class Foo extends mixin(ExtensibleArray) {}
示例
🌐 Examples
在
class Test {
constructor(name) {
this.name = name;
}
logger() {
console.log("Hello", this.name);
}
}
出
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Test = (function() {
function Test(name) {
_classCallCheck(this, Test);
this.name = name;
}
Test.prototype.logger = function logger() {
console.log("Hello", this.name);
};
return Test;
})();
安装
🌐 Installation
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/plugin-transform-classes
yarn add --dev @babel/plugin-transform-classes
pnpm add --save-dev @babel/plugin-transform-classes
bun add --dev @babel/plugin-transform-classes
用法
🌐 Usage
使用配置文件(推荐)
🌐 With a configuration file (Recommended)
// without options
{
"plugins": ["@babel/plugin-transform-classes"]
}
// with options
{
"plugins": [
["@babel/plugin-transform-classes", {
"loose": true
}]
]
}
通过 CLI
🌐 Via CLI
babel --plugins @babel/plugin-transform-classes script.js
通过 Node API
🌐 Via Node API
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-classes"],
});
选项
🌐 Options
loose
boolean,默认值为 false。
考虑迁移到顶层 assumptions,它可以对 Babel 应用的各种 loose 模式扣除进行精细控制。
{
"assumptions": {
"constantSuper": true,
"noClassCalls": true,
"setClassMethods": true,
"superIsCallableConstructor": true
}
}
方法可枚举性
🌐 Method enumerability
请注意,在松散模式下类方法是可枚举的。这与规范不符,可能会遇到问题。
🌐 Please note that in loose mode class methods are enumerable. This is not in line with the spec and you may run into issues.
方法赋值
🌐 Method assignment
在宽松模式下,方法是通过简单赋值在类的原型上定义的,而不是直接定义的。这可能导致以下情况无法使用:
🌐 Under loose mode, methods are defined on the class prototype with simple assignments instead of being defined. This can result in the following not working:
class Foo {
set bar() {
throw new Error("foo!");
}
}
class Bar extends Foo {
bar() {
// will throw an error when this method is defined
}
}
当定义 Bar.prototype.foo 时,它会触发 Foo 的 setter。这种情况在生产代码中很少出现,不过还是值得注意。
🌐 When Bar.prototype.foo is defined it triggers the setter on Foo. This is a
case that is very unlikely to appear in production code however it's something
to keep in mind.
你可以在这里了解更多关于配置插件选项的内容