JavaScript - 实例的复制方法

JavaScript - Copy Method of Instance

我想要复制 class 实例的所有 properties/methods :

class A {
    get prop1() { return 1; }
    get prop2() { return 2; }

    doStuff() {
        return this.prop1 + this.prop2;
    }
}

class B extends A {
   get prop1() { return 5; }
}
class AWrapper {
    constructor(a) {
        // [1] Copy all methods/propertys of a
        this.doStuff = () => a.doStuff() + 42;
    }
}

const a = new A();
const b = new B();
const wA = new AWrapper(a);
const wB = new AWrapper(b);
console.log(a.prop1(), wA.prop1(), wB.prop1()); // 1, 1, 5
console.log(a.doStuff(), wA.doStuff()); // 3, 45

我可以手动复制每个 method/property,但是是否有针对 [1] 的简单命令,使得 wA 具有与 a 相同的签名?

使用 extends 关键字并调用父项的 (A) doStuffthis.doStuff = () => super.doStuff() + 42;

class A {
  get prop1() { return 1; }
  get prop2() { return 2; }

  doStuff() {
      return this.prop1 + this.prop2;
  }
}

class AWrapper extends A {
  constructor(...args) {
    super(...args);     
      this.doStuff = () => super.doStuff() + 42;
  }
}

const a = new A();
const w = new AWrapper(a);

console.log(a.prop1, w.prop1); // 1, 1
console.log(a.doStuff(), w.doStuff()); // 3, 45

下面应该做。

class A {
    get prop1() { return 1; }
    get prop2() { return 2; }

    doStuff() {
        return this.prop1 + this.prop2;
    }
}
class AWrapper extends A{
    constructor(a) {
        super(a);
        this.doStuff = () => a.doStuff() + 42;
    }
}
const a = new A();
const wA = new AWrapper(a);
const wB = new AWrapper(a);
console.log(a.prop1, wA.prop1, wB.prop1); // 1, 1, 1
console.log(a.doStuff(), wA.doStuff()); // 3, 45

你还需要制作一个BWrapper class - 除此之外,extendssuper 是你所需要的:

class A {
  get prop1() {
    return 1;
  }
  get prop2() {
    return 2;
  }

  doStuff() {
    return this.prop1 + this.prop2;
  }
}

class B extends A {
  get prop1() {
    return 5;
  }
}

class AWrapper extends A {
  constructor(a) {
    super();
    this.doStuff = () => a.doStuff() + 42;
  }
}

class BWrapper extends B {
  constructor(b) {
    super();
    this.doStuff = () => b.doStuff() + 42;
  }
}

const a = new A();
const b = new B();
const wA = new AWrapper(a);
const wB = new BWrapper(b);
console.log(a.prop1, wA.prop1, wB.prop1); // 1, 1, 5
console.log(a.doStuff(a), wA.doStuff(wA)); // 3, 4

通常,Proxy 是使用 mixins 或装饰器时的首选工具:

class A {
    get prop1() {
        return 1;
    }

    get prop2() {
        return 2;
    }

    doStuff() {
        return this.prop1 + this.prop2;
    }
}


class B extends A {
    get prop1() {
        return 5;
    }
}


function decorate(target) {
    let mixin = {
        doStuff() {
            return target.doStuff() + 42;
        }
    }

    return new Proxy(target, {
        get(_, prop) {
            return (prop in mixin) ? mixin[prop] : target[prop];
        }
    });
}


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

const wA = decorate(a)
const wB = decorate(b)

console.log(a.prop1, wA.prop1, wB.prop1); // 1, 1, 5
console.log(a.doStuff(), wA.doStuff()); // 3, 45