我有三个coffeescript类,设置如下:
class A
class C extends A
class B
所以原型链看起来像这样:
A -> C
B
我需要原型链看起来像这样:
A -> B -> C
问题是我不能触及A和C的定义。
我想做的是做一个注入函数,它可以像这样调用:
inject B, C
这将B注入到A之前的C的原型链中,然后将B的原型链设置为注入之前的任何C的原型链。
我想这会很简单,就像
C extends (B extends C.prototype)
但不幸的是,事情并不是那么简单,因为coffeescript所做的所有的原型/__超级__魔法。有没有人知道如何注入原型链,这样基本上就像你说的class C extends B
和class 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
发布于 2011-08-27 04:15:06
更新:我最初回答说C extends B; B extends A
可以工作。这确实会使C instanceof B
和B 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类的内部工作原理,您可能想要查看my book on CoffeeScript,它是由PragProg的优秀人员发布的。:)
https://stackoverflow.com/questions/7206621
复制相似问题