详解babel是如何将class语法糖转换为es5的语法

 更新时间:2024年02月18日 09:07:52   作者:xxyCoder  
这篇文章主要详细介绍了babel是如何将class语法糖转换为es5的语法,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

准备工作

  • 在目录下创建两个文件,分别是index.js和.babelrc
class Parent {
    static type = 'Parent';
    #salary = 0;
    name = '';
    static showType() {
        console.log(this.type)
    }
    #seeSalary() {
        console.log(this.#salary)
    }
    speakName() {
        this.#seeSalary()
        console.log(this.name)
    }
}

class Child extends Parent {
    constructor(name) {
        super();
        this.name = name;
    }
    speakName() {
        super.speakName();
    }
}
{
    "presets": [
        "@babel/preset-env"
    ]
}
npm install @babel/core @babel/cli @babel/preset-env --save-dev
npx babel index.js -o dist.js

编译后私有变量和方法怎么存储?

var _salary = new WeakMap();
var _seeSalary = new WeakSet();
var Parent = function () {
  function Parent() {
    _classPrivateMethodInitSpec(this, _seeSalary);
    _classPrivateFieldInitSpec(this, _salary, {
      writable: true,
      value: 0
    });
  }
}
function _seeSalary2() {
  console.log(_classPrivateFieldGet(this, _salary));
}

function _classPrivateMethodInitSpec(obj, privateSet) {
  privateSet.add(obj); 
}
function _classPrivateFieldInitSpec(obj, privateMap, value) {
  privateMap.set(obj, value);
}

  • 总结这部分代码:私有变量会存储在weakMap中,键是对象,值是变量值;私有方法存储在weakSet中,键是对象。对于方法存储了对象还不够,执行方法是需要函数体的,函数体定义在外部。
  • 问题是,我调用的是seeSalary又不是seeSalary2。首先要说的是,私有方法只能在类方法中调用,外部是没办法调用的,那么在方法中调用的时候会对调用seeSalary进行拦截去执行seeSalary2
  • 还有一个问题,调用babel转换为es5的语法,怎么还有weakMapweakSet呢?Babel 是包含编译和polyfill两部分的。

编译后静态或公开变量和方法怎么存储?

var Parent = function() {
  function Parent() {
    ...
    _defineProperty(this, "name", '');
  }
  // 第一个参数是public方法,第二个参数是static方法
  _createClass(Parent, [{
    key: "speakName",
    value: function speakName() {
      _classPrivateMethodGet(this, _seeSalary, _seeSalary2).call(this);
      console.log(this.name);
    }
  }], [{
    key: "showType",
    value: function showType() {
      console.log(this.type);
    }
  }]);
  return Parent;
}
_defineProperty(Parent, "type", 'Parent');

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 _classPrivateMethodGet(receiver, privateSet, fn) { 
  if (!privateSet.has(receiver)) { 
    throw new TypeError("attempted to get private field on non-instance"); 
  } 
  return fn; 
}
  • 总结这部分代码:public的属性会定义在实例自身上,public的方法会定义在构造器的prototype身上;static的属性和方法都会定义在类自身上。

那么继承是怎么实现的?

var Child = function(_Parent2) {
  _inherits(Child, _Parent2);
  function Child(name) {
    var _this;
    _this = _callSuper(this, Child);
    _this.name = name;
    return _this;
  }
  _createClass(Child, [{
    key: "speakName",
    value: function speakName() {
      _get(_getPrototypeOf(Child.prototype), "speakName", this).call(this);
    }
  }]);
  return Child; 
}(Parent);

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } });
  Object.defineProperty(subClass, "prototype", { writable: false });
  if (superClass) _setPrototypeOf(subClass, superClass); 
}
function _setPrototypeOf(o, p) { 
  _setPrototypeOf = Object.setPrototypeOf ?
    Object.setPrototypeOf.bind() :
    function _setPrototypeOf(o, p) { o.__proto__ = p; return o; };
  return _setPrototypeOf(o, p);
}
function _callSuper(t, o, e) {
  return o = 
    _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? 
      Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) :
      o.apply(t, e)); 
}

  • 总结这部分代码:继承是通过修改子类的prototype指向了一个新对象,新对象的prototype指向了父类的prototype,且新对象的constructor保持子类的constructor不变且允许外部代码修改。然后将子类的prototype拒绝被赋值为其他对象。最后将子类的__proto__指向父类。
  • 有个问题,为什么要创建一个新对象而不是让子类的prototype直接指向父类的prototype呢?这是因为在之前代码中给子类prototype添加公开方法的时候避免影响父类。
  • 还有一个问题,为什么需要__proto__指向父类呢?这是为了静态属性和方法也能让子类调用到父类的,前面也提到了静态的方法和属性都是挂载到类自身。

拓展:原型链

  • 每个对象(数组、函数等)都有__proto__属性,通过该属性指向其他对象串联出原型链
  • 函数不仅仅有__proto__还有prototype,但是寻找原型链并不会经过prototype,除非你是new了一个类,因为new关键字将类的prototype作为实例__proto__的值了。

例子

  • 例一
function P() {}
P.prototype.x = 'x'

function C() {}
C.prototype = P.prototype
console.log(C.x) // undefined
  • 例二
function P() {}
P.prototype.x = 'x'
P.x = 'xxx'

function C() {}
C.__proto__ = P;
console.log(C.x)  // xxx

以上就是详解babel是如何将class语法糖转换为es5的语法的详细内容,更多关于babel class转换为es5的资料请关注脚本之家其它相关文章!

相关文章

  • javascript简单实现表格行间隔显示颜色并高亮显示

    javascript简单实现表格行间隔显示颜色并高亮显示

    表格行间隔显示颜色并实现高亮显示,这种效果大家都有见到过吧,下面就为大家详细介绍下,需要的朋友可不要错过
    2013-11-11
  • 详解JSON Web Token 入门教程

    详解JSON Web Token 入门教程

    这篇文章主要介绍了详解JSON Web Token 入门教程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • 2016年最热门的15 款代码语法高亮工具,美化你的代码

    2016年最热门的15 款代码语法高亮工具,美化你的代码

    无论是代码高亮还是语法高亮对整个程序来说都非常重要,可以给人眼前一亮的感觉,增加用户体验度,下面通过本文给大家介绍2016年最热门的Javascript代码高亮显示脚本及代码语法高亮工具,对js代码高亮,代码语法高亮相关知识感兴趣的朋友一起学习吧
    2016-01-01
  • JavaScript中if、else if、else和switch的语法、用法及注意事项

    JavaScript中if、else if、else和switch的语法、用法及注意事项

    这篇文章主要介绍了JavaScript中的条件判断语句,包括if、elseif、else和switch的基本语法、用法及注意事项,通过这些语句,可以根据不同的条件执行相应的代码块,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-04-04
  • 原生js实现的贪吃蛇网页版游戏完整实例

    原生js实现的贪吃蛇网页版游戏完整实例

    这篇文章主要介绍了原生js实现的贪吃蛇网页版游戏完整实例,可实现自主选择游戏难度进行贪吃蛇游戏的功能,涉及javascript键盘事件及页面元素的操作技巧,需要的朋友可以参考下
    2015-05-05
  • 通过seajs实现JavaScript的模块开发及按模块加载

    通过seajs实现JavaScript的模块开发及按模块加载

    seajs实现了JavaScript 的 模块开发及按模块加载。用来解决繁琐的js命名冲突,文件依赖等问题,其主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载。下面我们来一起深入学习下吧
    2019-06-06
  • 常见JS前端接口校验方式总结

    常见JS前端接口校验方式总结

    作为一名优秀的接口调用工程师,对接口的返回信息进行校验是必不可少的,本文整理的是一些常用的校验方式,希望能够对大家有所帮助
    2023-05-05
  • javascript实现将数字转成千分位的方法小结【5种方式】

    javascript实现将数字转成千分位的方法小结【5种方式】

    这篇文章主要介绍了javascript实现将数字转成千分位的方法,结合实例形式分析了5种常用的数字转换的常用方法,涉及字符串与正则操作的相关技巧,需要的朋友可以参考下
    2016-12-12
  • 详解 javascript对象创建模式

    详解 javascript对象创建模式

    这篇文章主要介绍了详解 javascript对象创建模式的相关资料,帮助大家更好的理解和学习JavaScript的相关知识。感兴趣的朋友可以了解下
    2020-10-10
  • 正则中的回溯定义与用法分析【JS与java实现】

    正则中的回溯定义与用法分析【JS与java实现】

    这篇文章主要介绍了正则中的回溯定义与用法,结合实例形式分析了回溯的概念、功能并提供了JS与java实现方法,需要的朋友可以参考下
    2016-12-12

最新评论