从babel编译结果分析class的实现原理

示例:

class A {
    // 属性表达式
    prop1 = 1;
    // get方法
    get value() {
      console.log('Getting the current value!');
      return this.prop1;
    }
    // set方法
    set value(newValue) {
      console.log('Setting the current value!');
      this.prop1 = newValue;
    }
    // 箭头函数表达式
    arrowFunc = (...args) => {
        console.log(args);
    }
    // constructor
    constructor(b = 2) {
        this.prop2 = b;
    }
    // 普通函数表达式
    Func() {
        console.log("Func");
    }
    // 静态属性
    static prop3 = 3;
    // 静态普通函数
    static staticFunc() {
        console.log("staticFunc", this);
    }
    // 静态箭头函数
    static staticArrowFunc = () => {
        console.log("staticArrowFunc", this);
    }
}
const a = new A(3);

使用babel编译成es5的代码,编译结果会生成几个内部函数:

// 类的调用检查,如果调用A不使用new,则会报错
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, descriptor.key, descriptor);
  }
}
// 定义原型上的普通函数、静态普通函数、get和set方法
function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}
// 定义属性到obj上,重新赋值使用defineProperty,第一次赋值直接添加属性
function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}

类的编译结果: 

// A是一个立即执行函数 返回结果是个函数 函数名就是类名
var A = /*#__PURE__*/ (function () {
  // constructor
  function A() {
    // 转化constructor中的默认参数
    var b =
      arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
    // 检查类是否使用new执行
    _classCallCheck(this, A);
    // 属性表达式定义到类实例上
    _defineProperty(this, "prop1", 1);
    // 箭头函数表达式定义到类实例上
    _defineProperty(this, "arrowFunc", function () {
      // 这个for循环是转换...args,遍历arguments,将每一项赋值给args对象
      for (
        var _len = arguments.length, args = new Array(_len), _key = 0;
        _key < _len;
        _key++
      ) {
        args[_key] = arguments[_key];
      }
      console.log(args);
    });
    this.prop2 = b;
  }

  _createClass(
    A,
    [
      {// get和set方法
        key: "value",
        get:
          function get() {
            console.log("Getting the current value!");
            return this.prop1;
          },
        set: function set(newValue) {
          console.log("Setting the current value!");
          this.prop1 = newValue;
        }
      },
      {// 普通函数表达式
        key: "Func",
        value: function Func() {
          console.log("Func");
        }
      }
    ],
    [
      {// 静态普通函数
        key: "staticFunc",
        value: function staticFunc() {
          console.log("staticFunc", this);
        }
      }
    ]
  );

  return A;
})();
// 静态属性定义到类上
_defineProperty(A, "prop3", 3);
// 静态箭头函数定义到类上
_defineProperty(A, "staticArrowFunc", function () {
  console.log("staticArrowFunc", A);
});

var a = new A(3);

下图可描述整个编译结果: 

需要注意的是:

  • 类原型上的方法、类的静态方法、类的get和set方法默认是不可枚举的
  • 类实例上的方法和属性、类的静态箭头函数是可枚举的

之后再出一章class继承的相关内容

推荐阅读:

CSS 超出隐藏实现限制字数的功能代码(多浏览器支持)

JS函数集合大全

Javascript中最常用的61段经典代码

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

短暂又灿烂的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值