@aboutweb/proxyclass 中文文档教程

发布于 6年前 浏览 27 项目主页 更新于 3年前

proxy-class

一种组织多重继承的无缝方式。

注意这个函数使用 ES6 代理Sets符号。 如果您想要 ES5 方法,请使用 Ring.js 或类似的库。

如果可以的话,你应该总是喜欢其他模式,比如装饰器或注释,因为 javascript 不支持这个有充分的理由:

  • must have the same arguments signiture
  • hard to isolate instances
  • overhead

ProxyClass(...mixins)

使用 ProxyScope 来反映对所有 mixinsprototype 的所有更改。

ProxyClass.hasInstance(...mixins)

允许通过覆盖所有 Subclass[Symbols.hasInstance] 来使用 instanceof警告:这会使 instanceof 的开销更高。

Examples

const EventEmitter = require('events');
const listen = ["on", "once"];

class ArrayEmitter extends ProxyClass.hasInstance(Array, EventEmitter) {
    constructor(options) {
        let { data } = options;

        super(...data);

        listen.forEach((property) => {
            let type = options[property];

            if(type) {
                for(let event in type) {
                    let listeners = type[event];

                    if(!Array.isArray(listeners)) {
                        listeners = [listeners];
                    }

                    listeners.forEach((listener) => {
                        this[property](event, listener)
                    });

                }
            }
        });

        this.emit("push", data);
    }
    push(...args) {
        super.push(...args);
        this.emit("push", args);
    }
}

let input = ["fubar", "haha"];

let ae = new ArrayEmitter({
    data : input,
    on : {
        push(...args) {
            console.log("every push", args);
        }
    },
    once : {
        push(...args) {
            console.log("inital push", args);
        }
    }
});

ae.push("last");

//will be true
na instanceof ArrayEmitter;
na instanceof Array;
na instanceof EventEmitter;

深层类

class A {
  constructor() {
    this.aProp = true;
        this.shared = "sharedA";
  }
  get isA() {
      return true;
  }
    get sharedA() {
        return this.shared;
    }
    sharedAFn() {
        return this.shared;
    }
}

class B { get isB() { return true; } }

class C extends ProxyClass.hasInstance(A, B) {
  get isC() { return true; }
}

class D {
  get isD() { return true; }
}

class E extends ProxyClass.hasInstance(C, D) {
  constructor() {
      super();

      this.eProp = true;
  }
  get isE() { return true; }
};

//You can also inline your class

var F = ProxyClass.hasInstance(class {
  constructor(someArg) {
      this.someArg = someArg;
      this.fProp = true;
  }
  get isF() {
      return true;
  }
}, E);


var e = new E();

//all of this will return true
e instanceof Object;
e instanceof A;
e instanceof B;
e instanceof C;
e instanceof D;
e instanceof E;

e.isA;
e.isB;
e.isC;
e.isD;
e.isE;
e.aProp;
e.eProp;

var f = new F("fubar");

//same as e plus
f instanceof F;
f.isF;
f.fProp;
f.someArg == "fubar";

Isolation

所有类成员函数都将使用它们自己的隔离上下文进行调用。

expect(e.shared).toEqual("sharedE");
expect(e.sharedA).toEqual("sharedA");
expect(e.sharedAFn()).toEqual("sharedA");

Dependancies

Licence

国际学习中心

proxy-class

A seemless way to organize multi inheritance.

Caution this function uses ES6 Proxies, Sets and Symbols. Use Ring.js or similar libaries, if you want an ES5 approach.

You should always prefer other patterns like decorators or annotions if you can, because javascript does not support this for good reasons:

  • must have the same arguments signiture
  • hard to isolate instances
  • overhead

ProxyClass(...mixins)

Uses ProxyScope to reflects all changes to prototype of all mixins.

ProxyClass.hasInstance(...mixins)

Allows the use of instanceof by overwriting all Subclass[Symbols.hasInstance]. Caution: this will make instanceof more expensive.

Examples

const EventEmitter = require('events');
const listen = ["on", "once"];

class ArrayEmitter extends ProxyClass.hasInstance(Array, EventEmitter) {
    constructor(options) {
        let { data } = options;

        super(...data);

        listen.forEach((property) => {
            let type = options[property];

            if(type) {
                for(let event in type) {
                    let listeners = type[event];

                    if(!Array.isArray(listeners)) {
                        listeners = [listeners];
                    }

                    listeners.forEach((listener) => {
                        this[property](event, listener)
                    });

                }
            }
        });

        this.emit("push", data);
    }
    push(...args) {
        super.push(...args);
        this.emit("push", args);
    }
}

let input = ["fubar", "haha"];

let ae = new ArrayEmitter({
    data : input,
    on : {
        push(...args) {
            console.log("every push", args);
        }
    },
    once : {
        push(...args) {
            console.log("inital push", args);
        }
    }
});

ae.push("last");

//will be true
na instanceof ArrayEmitter;
na instanceof Array;
na instanceof EventEmitter;

Deep Classes

class A {
  constructor() {
    this.aProp = true;
        this.shared = "sharedA";
  }
  get isA() {
      return true;
  }
    get sharedA() {
        return this.shared;
    }
    sharedAFn() {
        return this.shared;
    }
}

class B { get isB() { return true; } }

class C extends ProxyClass.hasInstance(A, B) {
  get isC() { return true; }
}

class D {
  get isD() { return true; }
}

class E extends ProxyClass.hasInstance(C, D) {
  constructor() {
      super();

      this.eProp = true;
  }
  get isE() { return true; }
};

//You can also inline your class

var F = ProxyClass.hasInstance(class {
  constructor(someArg) {
      this.someArg = someArg;
      this.fProp = true;
  }
  get isF() {
      return true;
  }
}, E);


var e = new E();

//all of this will return true
e instanceof Object;
e instanceof A;
e instanceof B;
e instanceof C;
e instanceof D;
e instanceof E;

e.isA;
e.isB;
e.isC;
e.isD;
e.isE;
e.aProp;
e.eProp;

var f = new F("fubar");

//same as e plus
f instanceof F;
f.isF;
f.fProp;
f.someArg == "fubar";

Isolation

All class member function will get called with their own isolated context.

expect(e.shared).toEqual("sharedE");
expect(e.sharedA).toEqual("sharedA");
expect(e.sharedAFn()).toEqual("sharedA");

Dependancies

Licence

ISC

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文