2011-05-10 86 views
10

如何使用CoffeeScript扩展类,但将构造参数传递给super?扩展类并将所有构造函数参数传递给super

例如:

class List extends Array 
    # Some other stuff to make it work... 

list = new List(1,2,3) 

console.log list 
 
[1, 2, 3] 
+0

那岂不是很高兴这个问题分成两个分开;第一个是将构造函数的参数传递给super,第二个是关于'Array'的怪异行为? – Mitja 2015-03-28 22:45:33

回答

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

    toString: -> 
     @join('-') 

list = new List(1, 2) 

list.push(3) 

list.toString() 

=>

 
'1-2-3' 
+0

这将是一个很好的方式来传递所有参数到父对象的构造函数,但这是这个工作的情况:) – Acorn 2011-05-10 17:52:07

+1

因为数组没有'构造函数'的方法,这是不可能的......但是,那会很好。 =) – jejacks0n 2011-05-10 17:54:27

+0

这在严格模式下不起作用,因为在这种情况下“参数”不存在。 – monokrome 2013-01-07 16:51:33

24

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

class A 
    constructor: -> 
    console.log arg for arg in arguments 

class B extends A 

new B('foo') # output: 'foo' 

而且问题不在该数组没有一个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的构造与没有参数。

+0

感谢您的神奇解释! ''我建议实现List作为数组实例的包装器“”你会怎么做呢?一个简短的例子将非常感谢,如果你有时间! – Acorn 2011-05-10 20:53:00

+0

嗯,我的意思是,构造函数看起来像'@arr = Array :: slice.call arguments,0'(将参数方法转换为对象的标准方法),然后您将实现每个数组方法作为简单的传递(例如'push: - > @ arr.push.apply arr,arguments','toString: - > @ arr.toString()',...),然后添加你自己的'List'方法。 – 2011-05-10 22:13:52

+0

哦,哇,分别通过每种方法..这听起来有点繁琐:) – Acorn 2011-05-10 23:27:34

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

的思考?注释?建议?我没有想过的限制?让我知道。

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 
相关问题