跳到主要內容

@babel/plugin-transform-classes

資訊

此外掛包含在 @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
}]
]
}

透過 CLI

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

透過 Node API

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

選項

loose

布林值,預設為 false

注意

考慮轉移至頂層 assumptions,它提供對 Babel 應用各種 loose 模式推論的細緻控制。

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

方法列舉性

請注意,在寬鬆模式下類別方法可列舉的。這與規格不符,您可能會遇到問題。

方法指派

在寬鬆模式下,方法會使用簡單指派定義在類別原型上,而不是被定義。這可能會導致以下情況無法運作

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。這是一個不太可能出現在實際程式碼中的案例,但仍需要留意。

提示

您可以在這裡閱讀更多關於如何設定外掛選項的資訊