跳至主内容

@babel/plugin-transform-classes

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

信息

此插件已包含在 @babel/preset-env

注意事项

当扩展原生类时(例如 class extends Array {}),需要包装父类。这是为了解决两个问题:

  • Babel 使用 SuperClass.apply(/* ... */) 转译类,但原生类不可调用,因此这种情况下会抛出错误

  • 某些内置函数(如 Array)总是返回新对象。Babel 不应返回该对象,而应将其视为新的 this

该包装器可在 IE11 及支持 Object.setPrototypeOf__proto__ 回退方案的所有浏览器中使用。 不支持 IE ≤ 10。如需支持 IE ≤ 10,建议不要扩展原生类。

Babel 需要静态判断是否在扩展内置类。因此"混入模式"无法生效:

JavaScript
class Foo extends mixin(Array) {}

function mixin(Super) {
return class extends Super {
mix() {}
};
}

要解决此限制,可在继承链中添加额外类,使 Babel 能够包装原生类:

JavaScript
const ExtensibleArray = class extends Array {};

class Foo extends mixin(ExtensibleArray) {}

示例

输入

JavaScript
class Test {
constructor(name) {
this.name = name;
}

logger() {
console.log("Hello", this.name);
}
}

输出

JavaScript
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;
})();

安装

npm install --save-dev @babel/plugin-transform-classes

用法

通过配置文件(推荐)

JavaScript
// without options
{
"plugins": ["@babel/plugin-transform-classes"]
}

// with options
{
"plugins": [
["@babel/plugin-transform-classes", {
"loose": true
}]
]
}

通过命令行

Shell
babel --plugins @babel/plugin-transform-classes script.js

通过 Node API

JavaScript
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-classes"],
});

配置选项

loose

boolean,默认值 false

注意

建议迁移到顶层的 assumptions,它提供了对 Babel 各类 loose 模式推导的细粒度控制。

babel.config.json
{
"assumptions": {
"constantSuper": true,
"noClassCalls": true,
"setClassMethods": true,
"superIsCallableConstructor": true
}
}

方法的可枚举性

请注意在 loose 模式下类方法可枚举的。这不符合规范要求,可能导致问题

方法赋值

在 loose 模式下,方法通过简单赋值而非定义方式添加到类原型上,可能导致以下情况失效:

JavaScript
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。这种情况虽在生产代码中极少出现,但仍需注意

提示

你可以在此处阅读更多关于配置插件选项的信息。