Skip to content

名称:babel插件ES6系列函数作用域、类

目录:

一、@babel/plugin-transform-block-scoped-functions(函数作用域)

  1、实战

二、@babel/plugin-transform-classes(类)

字数:大约700字

Babel 插件是用于扩展 Babel 编译器的功能的组件,它们可以添加新的语法、转换器、插件等,以便更好地适应不同的开发需求。在前端开发中,Babel 插件通常与打包工具(如 webpack)一起使用,以便将 ES6+ 代码转换为向后兼容的 JavaScript 代码,并打包成浏览器可以识别的静态资源。

一、@babel/plugin-transform-block-scoped-functions(函数作用域)

也集成@babel/preset-env

"babel-plugin-block-scoped-functions"是Babel的一个插件,它可以将函数声明的作用域限制在当前块级作用域内。这意味着函数声明不再在整个函数作用域中可用,而是只能在函数声明所在的块级作用域内使用。

例如,以下代码片段:

js
if (true) {
  function foo() {
    console.log('foo');
  }
  foo();
}
foo();

转换后:

js
if (true) {
  let foo = function () {
    console.log('foo');
  };
  foo();
}
foo();

在转换后的代码中,函数声明被替换为函数表达式,并将其放置在一个块级作用域内。这样,函数就只能在该块级作用域内使用,而不是在整个函数作用域内使用。

1、实战

js
yarn add --dev @babel/plugin-transform-block-scoped-functions
js
// src/index.js
if (true) {
  function foo() {
    console.log('foo');
  }
  foo();
}
foo();

转译后

js
npx babel src/index.js -d dist
js
// src/dist/index.js
if (true) {
  let foo = function () {
    console.log('foo');
  };
  foo();
}
foo();

二、@babel/plugin-transform-classes(类)

也集成@babel/preset-env

在Babel中,@babel/plugin-transform-classes插件是用来将ES6的类语法转换为ES5的常规构造函数语法的。它主要用于支持一些ES6的类语法特性,例如类的静态方法、属性、继承和构造函数等。这个插件可以将这些特性转换为ES5的构造函数语法,以确保更好的浏览器兼容性。

例如,以下代码片段:

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

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

转换后:

js
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
let Test = /*#__PURE__*/function () {
  function Test(name) {
    _classCallCheck(this, Test);
    this.name = name;
  }
  _createClass(Test, [{
    key: "logger",
    value: function logger() {
      console.log("Hello", this.name);
    }
  }]);
  return Test;
}();

可以看到,插件"classes"将ES6类转换为了ES5函数,同时保留了继承关系和实例方法、静态方法等属性。使用该插件后,我们可以在不支持ES6的环境中使用ES6类的语法。上面即为实战。