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的转码基本不用。这次算是补补功课。