class to es5

119 阅读7分钟

class 编译es5

class Super {
    static c='static';
    w ='www';
    constructor(){
        this.a = 100
    }
    b =200;
    func1 = function () {}
    get value() {
        console.log('Getting the current value!');
      }
    age(){
        console.log(this.a)
    }
    static height(){
        console.log(this.b)
    }
}

// webpack转换后:
var Super = /*#__PURE__*/function () {
  function Super() {
   //1.判断是否是通过new 调用的构造函数:在构造函数内判断this 是否是构造函数的实例 this instanceof Super
    _classCallCheck(this, Super);
    //2.将class内定义的属性添加到实例对象(this) 上通过Object.defineProperty(this, 属性,value)
    _defineProperty(this, "w", 'www');
    _defineProperty(this, "b", 200);
    _defineProperty(this, "func1", function () {});
    //3.将 class constructor中定义的属性绑定到this上
    this.a = 100;
  }
  
  // _createClass(Super,[{原型方法},{}],[{静态方法}])将class里定义的方法添加到Super.prototype构造函数原型上,同时设置构造函数原型prototype的描述符writable:false 不可修改,
  // return Super;_createClass(Super,[{原型方法},{}],[{静态方法}])执行完最后返回Super;
  return _createClass(Super, [{
    key: "value",
    get: function get() {
      console.log('Getting the current value!');
    }
  }, {
    key: "age",
    value: function age() {
      console.log(this.a);
    }
  }], [{
    key: "height",
    value: function height() {
      console.log(this.b);
    }
  }]);
}();
// 5.绑定Super构造函数上的静态属性通过Object.defineProperty(构造函数,属性,{})
_defineProperty(Super, "c", 'static');

class 语法转es5:

第一步 定义一个和class Super同名的变量,然后赋值一个自执行函数

第二步 在执行函数内部 创建一个和class Super同名的构造函数 构造函数内执行如下操作: 1._classCallCheck(this,Super) 判断是否是通过new 调用的构造函数:在构造函数内判断this 是否是构造函数的实例 this instanceof Super 2.将class内定义的属性添加到实例对象(this) 上通过Object.defineProperty(this, 属性,value) 3.将 class constructor中定义的属性绑定到this上(例如:this.a = 100)

第三步 _createClass(Super,[{原型方法},{}],[{静态方法}])将class里定义的方法添加到Super.prototype构造函数原型上,同时设置构造函数原型prototype的描述符writable:false 不可修改

1.将class里定义的方法通过Object.defineProperty(构造函数原型,属性,{value:xxx})添加到上面定义的构造函数的原型(Constructor.prototype)上,

2.其中存储器方法也是挂载在构造函数的原型上的通过Object.defineProperty(构造函数原型,属性,get/set),

3.静态方法也是通过Object.defineProperty(构造函数,属性,{value:xxx}),添加到构造函数的上

第四步 在自执行函数内部最后返回构造函数Super(最终class被转换成构造函数)return Super;

第五步 自执行函数执行完---->再绑定Super构造函数上的静态属性通过Object.defineProperty(构造函数,属性,{})。

class Sub extends Super {
    static e='dddd';
    son="123";
    constructor() {
      super();
      this.x = 2;
    }
    test='456'
    func2 = function () {}
    get value2() {
        console.log('Getting the current value!');
      }
    m() {
      super.age(); // 调用父类构造函数原型上的方法
    }
    age2(){
        console.log('age2')
    }
    static height2(){
        console.log('height2')
    }
  }
  
  // webpack转换后:
  // _inherits():子类继承父类
  function _inherits(subClass, superClass) { 
  if (typeof superClass !== "function" && superClass !== null) { 
    throw new TypeError("Super expression must either be null or a function"); 
  } 
  // 将子类的构造函数的原型指向 以父类原型对象为原型创造出来的一个新对象,并将新对象的constructor指向子类构造函数
  subClass.prototype = Object.create(superClass && superClass.prototype, {
  constructor: { value: subClass, writable: true, configurable: true } });
  // 将子类的原型设置成不可修改
  Object.defineProperty(subClass, "prototype", { writable: false }); 
  // 设置子类构造函数sub的__proto__指向父类构造函数 super,执行super()时会用到
  if (superClass) _setPrototypeOf(subClass, superClass); 
}
var Sub = /*#__PURE__*/function (_Super2) {
  function Sub() {
    //1.声明一个_this 变量,初始值为undefined
    var _this;
    //2._classCallCheck(this,Sub) 判断是否是通过new 调用的构造函数:
    _classCallCheck(this, Sub);
    //3.初始化_this对象,_callSuper(this, Sub):通过Sub.__proto__获取到父类Super构造函数(下面第三步中设置的),然后执行 Super.call(this)调用父类的构造函数,this会绑定父类的属性,将_callSuper(this, Sub)执行返回的对象作为新实例 _this = _callSuper(this, Sub);
    _this = _callSuper(this, Sub);
    // 4.将class内定义的属性添加到新实例对象(_this)上通过Object.definproperty(_this,属性,value)
    _defineProperty(_this, "son", "123");
    _defineProperty(_this, "test", '456');
    _defineProperty(_this, "func2", function () {});
    //5.将 class constructor中定义的属性绑定到_this上
    _this.x = 2;
    //6.显示的返回_this
    return _this;
  }
  // 通过寄生式继承,Sub继承Supe
  _inherits(Sub, _Super2);
  // _createClass(Sub,[{原型方法},{}],[{静态方法}])Sub.prototype构造函数原型上,同时设置构造函数Sub的原型prototype的描述符writable:false 不可修改;
  return _createClass(Sub, [{
    key: "value2",
    get: function get() {
      console.log('Getting the current value!');
    }
  }, {
    key: "m",
    value: function m() {
    // 调用父类构造函数原型Sub.prototype上的方法
      _get(_getPrototypeOf(Sub.prototype), "age", this).call(this);
    }
  }, {
    key: "age2",
    value: function age2() {
      console.log('age2');
    }
  }], [{
    key: "height2",
    value: function height2() {
      console.log('height2');
    }
  }]);
}(Super);

class Sub extends Super 转es5

第一步 定义一个和class Sub 同名的变量,然后赋值一个自执行函数,自执行函数内部定义一个Sub 同名的函数,Super作为自执行函数参数传入,

第二步 在执行函数内部 创建一个和class Sub同名的构造函数构造函数内执行如下操作: 1.声明一个_this 变量,初始值为undefined,如果不执行第三步(也就是class的constructor中不写super())则第四步往_this绑定属性会报错;

2._classCallCheck(this,Sub) 判断是否是通过new 调用的构造函数:在构造函数内判断this 是否是构造函数的实例 this instanceof Sub

3.初始化_this对象,_callSuper(this, Sub):通过Sub.__proto__获取到父类Super构造函数(下面第三步中设置的),然后执行 Super.call(this)调用父类的构造函数,this会绑定父类的属性,将_callSuper(this, Sub)执行返回的对象作为新实例 _this = _callSuper(this, Sub);

4.将class内定义的属性添加到新实例对象(_this)上通过Object.definproperty(_this,属性,value)

5.将 class constructor中定义的属性绑定到_this上,_this.x = 2; 6.返回_this;(注意:继承的构造函数我们有显式的返回值,普通的构造函数只有隐式的返回this)

第三步 子类继承父类:_inherits(subClass, superClass)通过寄生式继承, 1.将子类的构造函数的原型指向 以父类原型对象为原型创造出来的一个新对象,并将新对象的constructor指向子类构造函数 2.将子类的原型设置成不可修改; 3._setPrototypeOf(subClass, superClass) //设置子类构造函数sub的__proto__指向父类构造函数 super

第四步 __createClass(Sub,[{原型方法},{}],[{静态方法}])Sub.prototype构造函数原型上,同时设置构造函数Sub的原型prototype的描述符writable:false 不可修改;

1.将class里定义的方法通过Object.defineProperty(构造函数原型,属性,{value:xxx})添加到上面定义的构造函数的原型(Constructor.prototype)上,

2.其中存储器方法也是挂载在构造函数的原型上的通过Object.defineProperty(构造函数原型,属性,get/set),

3.静态方法也是通过Object.defineProperty(构造函数,属性,{value:xxx}),添加到构造函数的上

第五步 在自执行函数内部最后返回构造函数Sub(最终class被转换成构造函数)return Sub;

第六步 自执行函数执行完---->再绑定Sub构造函数上的静态属性,通过Object.defineProperty(构造函数,属性,value)加到构造函数(Constructor)上。

class 继承时constructor为什么要先调用super? 因为class 继承时class构造函数定义了返回值(如果没定义返回值,则默认隐式返回值是this),该返回值是我们在构造函数内部自己定义的一个初始值为undefined 的变量, 如果不执行super(),则无法生成一个对象赋值给返回值,也就无法将我们在class里定义的属性添加到返回值上(也就是上面第三步的3和4两点不会执行)。

new一个构造函数或者class时发生了什么(4步)

1.创建一个新的空对象newObj=new Object();

2.将对象newObj.proto 属性指向构造函数的原型对象(Constructor.prototype) 1和2可以合并成一步,以构造函数的原型对象为原型创建一个新对象: newObj = Object.create(Constructor.prototype),

3.调用 构造函数.call(newOnj)方法;这样构造函数的this就指向我们新创建的空对象newObj

4.返回newObj

封装继承多态 类的多态:是在继承的基础上实现的,子类继承父类后通过重写父类的方法来实现多态

Sub1 extends Supre 子类Sub1继承父类Supre

Sub2 extends Supre 子类Sub2继承父类Supre

let classA = new Sub1() classA.age2() classA = new Sub2() // 通过给classA实例化不同的子类来实现多态 classA.age2()