什么是高阶类?

通俗一点来说,高阶类就是父类调用了子类才有的东西。比如这个例子:


class A{ constructor(){ this.username = 'vvheat'; } show(){ console.log(this.username); console.log(this.age); //父类A根本没有age这个属性 } } class B extends A{ constructor(){ super(); this.age = 18; } } let a = new B(); a.show();

从上面的代码中可以看到,父类当中根本没有age这个属性,但是在show方法中却调用了this.age,这种情况,必须在A的子类里有age,那么在实例化子类的时候才可以找到age。所以上面的代码会得到我们想要的结果:

那么这样到底有什么用呢?下面我们来利用「高阶类」来做一个「数据共享」的例子。

首先我们先创建一个Store.js:


class Store{ constructor(){ this._state = {}; } get(key){ if(key in this._state){ return this._state[key] }else{ throw new Error(`${key} is not defined`) } } set (key,value){ this._state[key] = value; } }

现在我需要实现一个效果,就是我在别的类当中,可以直接使用到Store里的getset方法,那么这个要怎么实现呢?这个时候,我们可以在Store类里添加一个「连接」方法:

class Store{
    constructor(){
        this._state = {};
    }
    get(key){
        if(key in this._state){
            return this._state[key]
        }else{
            throw new Error(`${key} is not defined`)
        }
    }
    set (key,value){
        this._state[key] = value;
    }

    //添加一个新的「连接方法」,只要传入这个方法里的类都可以调用set和get方法。
    connect(cls){
        const store = this;
        return class extends cls{
            constructor(...args){
                super(...args);
                this.get = store.get.bind(store);
                this.set = store.set.bind(store);
            }
        }
    }
}

let store = new Store()

这个新的connect方法接收一个类,一量一个类传入此方法,那么这个方法就返回一个新类,这个新类就拥有了store当中的setget方法了!

那么我要如何跟别的类来进行连接呢?我们来新建一个A.js:

const A = store.connect(class{
    test(){
        this.set('testA',10);
        console.log(this.get('testA'))
    }
})
const a = new A();

A这个类其实是connect方法返回的一个新类,这个新类其实是继承了我们传过去的一个匿名类,也就是说其实A是一个父类,父类调用了子类的方法来做数据的处理,这样就形成了高阶类的用法。
这个时候我们得到的结果是:

可以看到,我们先调用了set方法设置了testA,然后又调用了get方法得到了testA的值。

既然我们要做一个「数据共享」的例子,我们来通过两个文件来进行互动,首先把A.js改成取值的方法

const A = store.connect(class{
    getA(){
        console.log(this.get('a'))
    }
})
const a = new A();

然后再新建一个B.js用来设置数据:

const B = store.connect(class{
    setA(){
        this.set('a',100)
    }
})

然后我们在主入口做如下调用:

const a = new A();
const b = new B();

b.setA();
a.getA();

最终得到正确的结果:

这只是我对高阶类的一个初步认识,高级用法还要继续学习和挖掘。