es6 class 实践

Class in ES6

从es6开始引入了class这个语法糖,针对babel,或者tsc,转码后,类会变成什么样,这篇文章将阐述编译后的结果。

首先看看es5中的类的实现,举个栗子

function classA(){
  this.a='a';
  this.printA=function(){
    console.log(this.a);
  }
  let b='b';
  function printB(){
    console.log('invisible to child')
  }
}

let instanceA=new classA();
instanceA.a;   // 'a', 实例本身的属性
instanceA.printA()  //'a', 实例本身的方法

instanceA.b  // undefined
instanceA.printB()  // underfined

instanceA.__proto__=== classA.prototype   // true
instanceA.__proto__  //  {constructor:function classA(){xxxx}}

classA.prototype.printDoubleA=function(){console.log(`${this.a}${this.a}`)};
instanceA.printDoubleA()  //  'aa';

classA.staticPrint=function(){console.log('this is static print')}
instanceA.staticPrint()  // underfined

总结一下:

  • 在调用new classA 之前,构建这个对象 this={};this.__proto__={consturctor:function classA(){xxx}};
  • 然后相当于classA.call(this)
  • 由于classA没有返回值,所以,this就是实例。classA 中凡是赋值给this的,都将变成实例的属性。其他的对于实例而言,都是不可见的。
  • 构建实例后,如果给classA.prototype添加新的属性,那么对于实例而言,立刻可见
  • 如果给classA添加其他属性,那么对于实例而言就是不可见的,而添加的属性相当于类里面的static属性。

下面我来看一下es6中的类,通过babel 转码后变成es5会变成啥样,同样举个栗子

class ClassA{
  a;  
  printA(){
    console.log(this.a);
  }
  b='b';
  printB=function(){console.log(this.b)};
  static c='c';
  static printC(){
    console.log(ClassA.c);
  }
}

转码后的如下,

function ClassA(){
  this.a=null;
  this.b='b';
  this.printB=function(){console.log(this.b);}
}
ClassA.prototype.printA=function(){console.log(this.a)}
ClassA.c='c';
ClassA.printC=function(){console.log(ClassA.c)}

总结一下

  • es6中类的语法糖是通过原型链实现的
  • es6中类带有初始化的属性,最终会出现在类实例上面,包括属性,函数
  • es6中定义的函数,将出现在es5类函数的原型链上面
  • es6中定义的静态属性,将出现在es5类函数对象本身上面。

最后看看typescript,效果跟上面的babel 一样

class Base {
  a: string = '';
  printA() {
    console.log(this.a);
  }
  b: string = '';
  printB = () => {
    console.log(this.b);
  }
  static printC() {
    console.log('hello C');
  }
}

总结一下。

  • 平时基本上沉溺于typescript,基本上不写js。因为实在是太香了。所以对于babel的转码基本不用。这次算是补补功课。
posted @ 2022-11-29 19:52  kongshu  阅读(23)  评论(0编辑  收藏  举报