JavaScript 作为 class 的混入

JavaScript mixin as a class

我发现了这个创建 mixin 的技巧:

let fooMixin = {
    foo() {console.log('foo')},
};

class A {
    bar() {console.log('bar')}
}

Object.assign(A.prototype, fooMixin);

不过我更愿意对混合使用 class 语法。

我试过这个:

class FooMixinClass {
    foo() {console.log('foo')}
}

class B {
    bar() {console.log('bar')}
}

Object.assign(B.prototype, FooMixinClass.prototype);

let b = new B();
b.bar();
b.foo();

但出现此错误:

"bar"

TypeError: b.foo is not a function. (In 'b.foo()', 'b.foo' is undefined)"

我想知道为什么它不起作用,因为在运行时检查 FooMixinClass.prototype 会发现一个几乎与 fooMixin.

相同的对象

Fiddle: https://jsfiddle.net/a5ufjchz/

I would like to understand why it doesn't work, since inspecting FooMixinClass.prototype at runtime reveals an object almost identical to fooMixin.

关键字差不多。 class 上的方法不是 enumerable 并且 Object.assign() 仅复制 enumerable 而非继承的属性

效用函数:

class FooMixinClass {
  static foo() {
    console.log("foo, but static");
  }
  foo() {
    console.log('foo')
  }
}

class B {
  bar() {
    console.log('bar')
  }
}

function mixin(target, source) {
  // ignore the Function-properties
  const {name,length,prototype,...statics} = Object.getOwnPropertyDescriptors(source);
  Object.defineProperties(target, statics);
  // console.log("static", statics);

  // ignore the constructor
  const {constructor,...proto} = Object.getOwnPropertyDescriptors(source.prototype);
  Object.defineProperties(target.prototype, proto);
  // console.log("proto", proto);

  return target;
}

mixin(B, FooMixinClass);

let b = new B();
b.bar();
b.foo();
B.foo();
.as-console-wrapper{top:0;max-height:100%!important}