2011-05-10 88 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 
相關問題