@babel/plugin-transform-classes
此插件包含在 @babel/preset-env 中
¥This plugin is included in @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(/* ... */)转译类,但原生类不可调用,因此在这种情况下抛出。¥Babel transpiles classes using SuperClass.apply(/* ... */), but native classes aren't callable and thus throw in this case.
- 
一些内置函数(如 Array)总是返回一个新对象。Babel 应该将其视为新的this,而不是返回它。¥Some built-in functions (like Array) always return a new object. Instead of returning it, Babel should treat it as the newthis.
封装器适用于 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
输入
¥In
class Test {
  constructor(name) {
    this.name = name;
  }
  logger() {
    console.log("Hello", this.name);
  }
}
输出
¥Out
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。
¥boolean, defaults to false.
考虑迁移到顶层 assumptions,它提供对 Babel 应用的各种 loose 模式推导的精细控制。
¥Consider migrating to the top level assumptions which offers granular control over various loose mode deductions Babel has applied.
{
  "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 上的设置器。这种情况不太可能出现在生产代码中,但需要牢记。
¥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.