扩展类并将所有构造函数参数传递给super

时间:2011-05-10 17:03:57

标签: class coffeescript

如何使用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]

4 个答案:

答案 0 :(得分:24)

一般来说,这可以在没有附加代码的情况下工作;除非明确覆盖,否则使用父构造函数:

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()

将使用 no 参数调用A的构造函数。

答案 1 :(得分:8)

class List extends Array
    constructor: ->
        @push arguments...

    toString: ->
        @join('-')

list = new List(1, 2)

list.push(3)

list.toString()

<强> =&GT;

'1-2-3'

答案 2 :(得分:2)

在CoffeeScript中使用extends期望超类也在CoffeeScript中。如果您正在使用非CS类,例如Array在原始问题中,您可能会遇到问题。

这解决了我的一般情况。这有点像黑客,因为它使用的_super可能并不打算在编译的JS中使用。

class MyClass extends SomeJsLib

  constructor: ->
    _super.call @, arg1, arg2

或者如果您只想传递来自调用者的参数:

class MyClass extends SomeJsLib

  constructor: ->
    _super.apply @, arguments

答案 3 :(得分:-1)

在我对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)

思考?评论?建议?限制我没想过?让我知道。