ES6 类语法(class)的pollyfill解析

2022 年 4 月 9 日 星期六(已编辑)
/
17
这篇文章上次修改于 2024 年 7 月 20 日 星期六,可能部分内容已经不适用,如有疑问可询问作者。

ES6 类语法(class)的pollyfill解析

ES6的类继承其实是寄生-组合式继承的语法糖,本质上还是对原型的继承。

ES6 类继承代码

class Person {
    constructor(name,age) {
      this.name=name;
      this.age=age;
    }
  eating() {
      console.log(this.name+'eating')
  }
}

class student extends Person {
    constructor(name,age,sno){
    super(name,age)
      this.sno = son
    }
  study(){
  console.log(this.name+this.sno+'styding')
  }
}

语法降级

ES5中实现类语法降级:

"use strict";

function _typeof(obj) {
  "@babel/helpers - typeof";
  return (
    (_typeof =
      "function" == typeof Symbol && "symbol" == typeof Symbol.iterator
        ? function (obj) {
            return typeof obj;
          }
        : function (obj) {
            return obj &&
              "function" == typeof Symbol &&
              obj.constructor === Symbol &&
              obj !== Symbol.prototype
              ? "symbol"
              : typeof obj;
          }),
    _typeof(obj)
  );
}

function _inherits(subClass, superClass) {
  console.log(subClass);
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  // 创建一个空对象 并把父类的原型关联到这个空对象的原型上 在空对象上添加subClass的构造函数
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: { value: subClass, writable: true, configurable: true }
  });
  //将子类的原型配置为不可写
  Object.defineProperty(subClass, "prototype", { writable: false });
  //让函数subClass的__proto__指向superClass(静态方法的继承)
  if (superClass) _setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
  _setPrototypeOf =
    Object.setPrototypeOf ||
    function _setPrototypeOf(o, p) {
      o.__proto__ = p;
      return o;
    };
  return _setPrototypeOf(o, p);
}
//创建super
function _createSuper(Derived) {
  var hasNativeReflectConstruct = _isNativeReflectConstruct();
  return function _createSuperInternal() {
    var Super = _getPrototypeOf(Derived),
      result;
    if (hasNativeReflectConstruct) {
      var NewTarget = _getPrototypeOf(this).constructor;
      /**
       * Super: Person
       * arguments: 传入的参数
       * NewTarget: Student
       * Reflect.construct的作用是通过Super创建一个实例并将这个实例的原型的constructor指向NewTarget
      */
      result = Reflect.construct(Super, arguments, NewTarget);
    } else {
      result = Super.apply(this, arguments);
    }
    //返回这个实例
    return _possibleConstructorReturn(this, result);
  };
}

function _possibleConstructorReturn(self, call) {
  if (call && (_typeof(call) === "object" || typeof call === "function")) {
    return call;
  } else if (call !== void 0) {
    throw new TypeError(
      "Derived constructors may only return object or undefined"
    );
  }
  return _assertThisInitialized(self);
}

function _assertThisInitialized(self) {
  if (self === void 0) {
    throw new ReferenceError(
      "this hasn't been initialised - super() hasn't been called"
    );
  }
  return self;
}

function _isNativeReflectConstruct() {
  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  if (Reflect.construct.sham) return false;
  if (typeof Proxy === "function") return true;
  try {
    Boolean.prototype.valueOf.call(
      Reflect.construct(Boolean, [], function () {})
    );
    return true;
  } catch (e) {
    return false;
  }
}

function _getPrototypeOf(o) {
  _getPrototypeOf = Object.setPrototypeOf
    ? Object.getPrototypeOf
    : function _getPrototypeOf(o) {
        return o.__proto__ || Object.getPrototypeOf(o);
      };
  return _getPrototypeOf(o);
}

function _classCallCheck(instance, Constructor) {
  //类型检测 检查this是否是目标构造函数的实例 如果不是就表示没有用new调用
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
//为目标对象使用defineProperty添加属性
function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    //除非明确配置enumerable 否则不可枚举
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    //如果protoProp本身属性中有value 则设置为可写
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}
function _createClass(Constructor, protoProps, staticProps) {
// 如果protoProps数组有值 则调用defineProperties 为构造函数的原型添加(加工后的)属性
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
// 如果staticProps数组有值 则调用defineProperties 为构造函数的对象添加(加工后的)属性
  if (staticProps) _defineProperties(Constructor, staticProps);
  Object.defineProperty(Constructor, "prototype", { writable: false });
  return Constructor;
}
// 立即执行函数 防止变量污染  /*#__PURE__*/  纯函数 可被tree shaking
var Person = /*#__PURE__*/ (function () {
  function Person(name, age) {
    //类型检测 检查是否使用new调用 如果是直接调用 则抛出错误
    _classCallCheck(this, Person);

    this.name = name;
    this.age = age;
  }
  //创建类 _createClass
  _createClass(Person, [
    {
      key: "eating",
      value: function eating() {
        console.log(this.name + "eating");
      }
    }
  ]);

  return Person;
})();
var Student = /*#__PURE__*/ (function (_Person) {
  //继承_Person原型上的方法和静态方法
  _inherits(Student, _Person);
  //获取父类构造函数创建的实例(此时他的原型的constructor指向Student)
  var _super = _createSuper(Student);

  function Student(name, age, sno) {
    var _this;

    _classCallCheck(this, Student);
    //因为不能通过Person函数直接调用(不允许) 继承属性
    _this = _super.call(this, name, age);
    _this.sno = sno;
    return _this;
  }

  _createClass(Student, [
    {
      key: "study",
      value: function study() {
        console.log(this.name + this.sno + "styding");
      }
    }
  ]);

  return Student;
})(Person);
var stu = new Student('lihua',18,1)

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...