ES6Class
1. 用法
class Animal{
type='哺乳类';//声明到实例上
constructor(){}//相当于function Animal(){}
say(){}//放到原型上
get a(){}//放到原型上 相当于Object.defineProperty(Animal.prototype,a,{get(){ }})
static flag='动物'//静态属性 ES7 ES6只有静态方法
static get flag(){return '动物'}//ES6静态属性 相当于Object.defineProperty(Animal,a,{get(){ }})
}
2. ES5类的继承
//Object.setPrototypeOf( Child.prototype , Father.prototype );
Child.prototype = Object.create( Animal.prototype ,{ constructor : { value : Child } } );
//create原理
let create = (parentProto, constructor) => {
function fn() { };
fn.prototype = parentProto;
let newFn = new fn;
newFn.constructor = constructor;
return newFn;
}
3. ES6类的继承
call + Object.create() + Object.setPrototypeOf()
class Animal {
constructor(name) {
this.name = name;
}
static type() {
console.log('动物');
}
say() {
console.log('say');
}
}
class Tiger extends Animal {
constructor(name) {
super(name)//这里super===Animal
}
static type() {
super.type()//这里super===Animal
}
say() {
super.say()//这里super===Animal.prototype
}
}
4. new的原理
function mockNew(constructor, ...args) {
let obj = Object.create(null);
Object.setPrototypeOf(obj, constructor.prototype)
let value = constructor.call(obj, args);
return value != null && typeof value === 'object' ? value : obj;
}
5. 装饰器
在执行类之前可以进行包装,装饰器必须是一个函数,只能修饰类的属性和类的方法。参数分别是类的原型、装饰的key、和key对应的属性描述器。
//装饰器 必须是一个函数,只能修饰类 (类中的属性 还有类中的方法) 参数分别是 类的原型 装饰的key 和key对应的属性描述器
@type1('哺乳1')
@type2('哺乳2')
class Circle{
@readonly PI = 3.14;
@before
say(){
console.log('say')
}
}
// 对类进行扩展
function type1(type1){
console.log('t1')
return function(Constructor){
console.log('innerT1')
Constructor.type1 = type1
}
}
// 对类进行扩展
function type2(type2){
console.log('t2')
return function(Constructor){
console.log('innerT2')
Constructor.type2 = type2
}
}
//修饰属性
function readonly(CirclePrototype,key,descriptor){
descriptor.writable = false;
descriptor.enumerable = false;
}
//修饰方法
function before(CirclePrototype,key,descriptor){
let oldSay = descriptor.value; // 函数劫持
descriptor.value = function(){ // 将函数原有的逻辑 进行包装
console.log('before')
oldSay()
}
}
let c = new Circle();
c.say();
// 实验型语法 目前node不支持
// mixin 混合
let obj = {
name:'zf',
age:'10',
}
@mixin(obj)
class School{
}
function mixin(obj){
return function(Constructor){
Object.assign(Constructor.prototype,obj)
}
}
let school = new School;
console.log(school.name,school.age);