【问题标题】:Injecting a new class into the coffeescript inheritance chain将新类注入到咖啡脚本继承链中
【发布时间】:2011-11-04 14:49:35
【问题描述】:

我有三个咖啡脚本类,设置如下:

class A
class C extends A
class B

所以原型链看起来像这样:

A -> C
B

我需要原型链看起来像这样:

A -> B -> C

问题是我无法触及 A 和 C 的定义。

我想做的是创建一个可以像这样调用的注入函数:

inject B, C

在 A 之前将 B 注入到 C 的原型链中,然后将 B 的原型链设置为注入之前的 C 的原型链。

我认为这很简单,就像

C extends (B extends C.prototype)

但不幸的是,由于咖啡脚本的所有原型/__super__ 魔法,事情并没有那么简单。有谁知道如何注入原型链,基本上就像你说的 class C extends Bclass B extends A 首先?

非常感谢。

澄清:以下代码不起作用,因为无法复制属性。

class A
  foo: 1
class B
  bar: 2
class C extends A
  baz: 3

B extends A
C extends B

c = new C
console.log c.foo
console.log c.bar
console.log c.baz

【问题讨论】:

    标签: coffeescript


    【解决方案1】:

    [更新:我最初回答说C extends B; B extends A 会起作用。这确实使C instanceof BB instanceof A 变为true,但它不会根据需要复制原型属性。所以,我重写了答案。]

    让我们来看看这个:

    class A
      foo: 1
    class B
      bar: 2
    class C extends A
      baz: 3
    

    此时,C::foo 为 1,C::baz 为 3。如果我们再运行

    C extends B
    

    B (child.prototype = ...) 的实例覆盖C 的现有原型,因此只定义了C::bar

    当我们使用class X extends Y 语法时不会发生这种情况,因为属性仅在其原型被覆盖后才附加到X 的原型。所以,让我们围绕extends 编写一个包装器来保存现有的原型属性,然后恢复它们:

    inherits = (child, parent) ->
      proto = child::
      child extends parent
      child::[x] = proto[x] for own x of proto when x not of child::
      child
    

    将此应用于我们的示例:

    inherits B, A
    inherits C, B
    
    console.log new C instanceof B, new B instanceof A  # true, true
    console.log B::foo, B::bar, B::baz  # 1, 2, undefined
    console.log C::foo, C::bar, C::baz  # 1, 2, 3
    

    如果您想了解更多关于 CoffeeScript 类的内部工作原理,您可能想查看由 PragProg 的优秀人员发布的my book on CoffeeScript。 :)

    【讨论】:

    • 我试过了,它正确设置了构造函数链,但无法复制属性。 (请参阅我原来的问题的编辑。)只做一个 _.extends / __hasprop 测试是否安全?我不确定,因为看起来 __extends 应该已经这样做了,这就是我意识到我不知道自己在做什么的关键。 :-)
    • @So8res 是的。我已经重写了我的答案。
    • 谢谢!另一个快速的问题 - 有没有办法通过 C 访问 A,以便我可以再删除一行样板文件?
    • @So8res 正如我在原始答案中提到的,您可以写A.__super__.constructor 来获取A 的超类(最初是C)。
    猜你喜欢
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2013-06-28
    • 2013-01-09
    • 2013-03-03
    • 2011-12-18
    • 1970-01-01
    • 2019-02-23
    相关资源
    最近更新 更多