你会如何使用CoffeeScript扩展一个类,但是否将构造参数传递给super?
例如:
class List extends Array
# Some other stuff to make it work...
list = new List(1,2,3)
console.log list
[1, 2, 3]
一般来说,这无需额外的代码即可工作; 除非明确重写,否则将使用父构造函数:
class A
constructor: ->
console.log arg for arg in arguments
class B extends A
new B('foo') # output: 'foo'
问题不在于 Array 没有constructor
方法:
coffee> Array.constructor
[Function: Function]
问题只是Array
太奇怪了。虽然数组原则上"只是对象",但实际上它们的存储方式不同。因此,当您尝试将该构造函数应用于不是数组的对象时(即使它通过了instanceof Array
测试),它不起作用。
因此,您可以使用 Acorn 的解决方案,但随后您可能会遇到其他问题(特别是当您将List
传递给需要真正数组的东西时)。出于这个原因,我建议将List
实现为数组实例的包装器,而不是尝试使用来自本机对象类型的继承。
当我们讨论这个主题时,一个非常重要的澄清:当你单独使用super
时,它确实通过了所有参数!此行为是从 Ruby 借来的。所以
class B extends A
constructor: ->
super
将所有参数传递给A
的构造函数,而
class B extends A
constructor: ->
super()
将调用不带参数A
的构造函数。
class List extends Array
constructor: ->
@push arguments...
toString: ->
@join('-')
list = new List(1, 2)
list.push(3)
list.toString()
=>
'1-2-3'
中使用 extends
希望超类也在 CoffeeScript 中。如果您使用的是非 CS 类,例如 Array
在原始问题中,那么您可能会遇到问题。
这为我解决了一般情况。这有点黑客,因为它使用了可能不打算在编译的 JS 中使用的_super
。
class MyClass extends SomeJsLib
constructor: ->
_super.call @, arg1, arg2
或者,如果您只想通过调用方的参数传递:
class MyClass extends SomeJsLib
constructor: ->
_super.apply @, arguments
在我对javascript的探索中,我需要一种通用方法来创建一个具有动态数量的构造函数参数的类。如前所述,据我所知,这不适用于数组,它仅适用于咖啡脚本风格的类。
通过.apply
调用具有动态参数数量的特定函数很容易
args = [1, 2, 3]
f = measurement.clone
f.apply measurement, args
类可以扩展保存在变量中的类。因此,我们可以编写一个返回新子类的函数。
classfactory = (f) ->
class extension extends f
将它们放在一起,我们可以创建一个返回新子类的函数,在其中我们将参数apply
到超类的构造函数。
classwitharguments = (f, args) ->
class extension extends f
constructor: () ->
extension.__super__.constructor.apply @, args
使用这个新工厂
args = [1, 2, 3]
instance = new (classwitharguments Measurement, args)
思潮?评论?建议?我没有想到的限制?让我知道。