2013-08-05 79 views
2

我對Coffeescript樹實現中的意外行爲有疑問,並想知道是否有人可以提供幫助。我認爲問題在於錯誤的「這個」背景,但我不確定在哪裏放置箭頭來解決它。也許有人比我更瞭解咖啡腳本可以解釋這種行爲?CoffeeScript遞歸函數

class Node 
    uuid: undefined 

    constructor: (@uuid) -> 

class MultiNode extends Node 
    branches: {} 

    constructor: (args...) -> 
     super(args...) 

    print: (str = '') -> 
     console.log "#{str}Multiway<#{@uuid}>" 
     for value,node of @branches 
      if node? 
       node.print "#{str} " 

class LeafNode extends Node 
    value: undefined 

    constructor: (@value, args...) -> 
     super(args...) 

    print: (str = '') -> 
     console.log "#{str}Leaf<#{@uuid}>: #{@value}" 

tree = new MultiNode(1) 
subtree1 = new MultiNode(2) 
subtree1.branches["aa"] = new LeafNode("three",3) 
subtree1.branches["ab"] = new LeafNode("four",4) 
tree.branches["a"] = subtree1 
subtree2 = new MultiNode(5) 
subtree2.branches["ba"] = new LeafNode("six",6) 
subtree2.branches["bb"] = new LeafNode("seven",7) 
tree.branches["b"] = subtree2 
tree.print() 

這無限遞歸,我想是因爲我打算 的子節點對象的「打印」的情況下未設置。我會很感激任何指導。

D.

回答

0

我認爲這個問題是你如何定義branches

class MultiNode extends Node 
    branches: {} 

,重視branchesMultiNode類,以便所有MultiNode情況下,通過他們的原型共享完全相同@branches。由於顯而易見的原因,這會造成一大堆事情。你在類級定義的任何東西都是原型的一部分,除非你自己做,否則它們都不會被複制到實例中。

所有你需要做的是確保每個MultiNode實例都有自己的@branches

class MultiNode extends Node 
    constructor: (args...) -> 
     @branches = { } 
     super(args...) 
    #... 

演示:http://jsfiddle.net/ambiguous/vkacZ/

經驗法則:

從不定義可變值(Coffee | Java)腳本中的類/原型,總是在構造函數中定義這些每個實例(除非你想共享......)。


PS:你不必說了:

if node? 
    node.print "#{str} " 

你可以只這樣說:

node?.print "#{str} " 
+0

感謝您的幫助,我真的很感激。也許我只是變得很厚,但爲什麼我明顯得到不同的'@uuid'和'@value'實例時,爲什麼我的原始定義會共享「@branches」實例?我認爲如果我在類的原型中定義了「value = undefined」或「@value:undefined」,我會得到共享實例? – user2073604

+0

你用'@value = something_else'等替換'@ uuid'和'@ value'。這給了你隱藏原型版本的東西,你永遠不會注意到原型中的那些。用'@ branches',你可以直接用'@branches [x] = y'來修改它,所以你可以修改它而不用替換/映射引用。 –

+0

非常好,謝謝你的時間。我更熟悉Haskell,Erlang和F#等函數式語言,以及更傳統的面嚮對象語言,如C++,C#,Python等,我猜這真的很棒。我希望你的解釋也能幫助別人。 – user2073604