2012-01-27 58 views
2

当我尝试在咖啡脚本中编写多个构造函数时,出现此错误:cannot define more than one constructor in a class咖啡脚本中的多个构造函数

我怎样才能做到这一点:

class Vector2 
    x: 0 
    y: 0 

    constructor:() -> 

    constructor:(@x, @y) -> 

    constructor:(vector) -> 
    x = vector.x 
    y = vector.y 

我想有一个空的构造和其他2层的构造。这可能吗?

回答

11

简单做,在CoffeeScript的方式:

class Vector 
    constructor:(@x=0,@y=0) -> 
     if typeof @x is "object" 
     [email protected] 
     @x=vector.x 
     @y=vector.y 

### 
test start 
### 
v=new Vector() 
console.log v.x,v.y 
v=new Vector(1,1) 
console.log v.x,v.y 
v=new Vector {x:1,y:1} 
console.log v.x,v.y 
### 
test end 
### 
3

不,这是不可能的。你可以使用参数对象。只是一个例子,这可能是更好的:

constructor:() -> 
    switch arguments.length 
     when 0 
      //no args 
     when 1 
      // vector 
     when 2 
      // coords 

这里的票要求超载的功能,没有补丁提交和阿什克纳斯关闭它:https://github.com/jashkenas/coffee-script/issues/531

+0

'arguments'应该是参数还是那只是在那里? – 2012-01-27 01:36:21

+1

'arguments'是一个魔术对象,一个伪数组,在JavaScript中是可用的函数。 https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments – JaredMcAteer 2012-01-27 01:37:55

+0

For CoffeeScriptification :) 可以使用'constructor:(args ...) - > switch args.length ...' – jonasfj 2013-01-17 12:44:53

1

更具体地说明为什么在JavaScript中不可能这样做,以及在CoffeeScript中也是这样: JavaScript不允许重载方法,因为方法只是h灰密钥对象的(无论是this,一个原型this - 或者,如果使用的是一个函数式的上下文堆栈对象)。因此,方法只能通过他们的名字来识别,而不能通过他们的整个签名(params通过或返回值)来识别。因此,使用相同的函数,您可以使用arguments伪阵列动态读取实际传递的参数。

0

正如JaredMcAteer所述,多个构造函数在技术上并不可行,但island205的建议达到了相同的效果。

作为另一种选择,如何使用类方法或具有有意义名称的普通函数来处理多个构造函数?用你的例子,这个怎么样?

class Vector2 
    constructor:(@x, @y) -> 

    @copy:(vector2) -> new Vector2(vector2.x, vector2.y) 

    @zero:() -> new Vector2(0, 0) 

然后你可以使用它像这样:

a = new Vector2(1, 2) 
=> Vector2 { x: 1, y: 2 } 
    b = Vector2.zero() 
=> Vector2 { x: 0, y: 0 } 
    c = Vector2.copy(a) 
=> Vector2 { x: 1, y: 2 }