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()