2013-08-05 82 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