2011-05-18 122 views
5

我在这里做错了什么?我为我的回调使用了胖箭头=>,但是当代码达到cb.onEndElement并调用@returner时,我得到一个空对象异常。那么,为什么@returner不存在?为了将其绑定到的Parser实例CoffeeScript范围问题

class Parser 
    constructor:() -> 
     @returner = (data) -> 

    searchParser: new xml.SaxParser (cb) => 
     cb.onStartElementNS (elem, attrs, prefix, url, ns) => 
      if elem is "results" then @results = [] 
      else if elem is "title" then @curr = "title" 
      else @curr = "none" 
     cb.onCdata (cdata) => 
      if @curr is "title" then @book.title = cdata 
     cb.onEndElementNS (elem, prefix, url) => 
      @results.push @book if elem is "book" 
     cb.onEndDocument => 
      @returner @results 

    search: (str, callback) -> 
     @returner = callback 
     @searchParser.parseString str 

p = new Parser 
p.search "somexml", (data) -> 
    console.log JSON.stringify data 
+0

我的答案解决了您的问题吗? – nicolaskruchten 2011-05-18 22:43:14

+0

是的,谢谢。 – Matthew 2011-05-23 19:32:41

回答

5

你的方法search需要一个胖箭头=>

此外,尽管行searchParser: new xml.SaxParser (cb) =>编译,这可能不是做你想做的,因为脂肪箭头回调结合Parser而不是this。你有两个选择:

  1. 你应该在你的构造函数把@searchParser = new xml.SaxParser (cb) => ...代替,给您呼叫的方式。
  2. 否则,你可以使用searchParser:() => new xml.SaxParser (cb) =>与括号低了下去叫它:@searchParser().parseString str,这将创建一个绑定到this

一个searchParser方法作为一个例子,这里有我的两个解决方案,以及您的原线,略微简化,以及经编译的代码,用于比较和对比的目的:在CoffeeScript的

简化的例子:

class Parser 
    constructor:() -> @searchParser1 = new xml.SaxParser (x) => console.log(x) 
    searchParser2:() => new xml.SaxParser (x) => console.log(x) 
    searchParser: new xml.SaxParser (x) => console.log(x) 

编译的JavaScript:

var Parser; 
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; 
Parser = (function() { 
    function Parser() { 
    this.searchParser2 = __bind(this.searchParser2, this);  
    this.searchParser1 = new xml.SaxParser(__bind(function(x) { 
     return console.log(x); 
    }, this)); 
    } 
    Parser.prototype.searchParser2 = function() { 
    return new xml.SaxParser(__bind(function(x) { 
     return console.log(x); 
    }, this)); 
    }; 
    Parser.prototype.searchParser = new xml.SaxParser(__bind(function(x) { 
    return console.log(x); 
    }, Parser)); 
    return Parser; 
}).call(this); 

注意如何searchParser1searchParser2有自己的回调势必thissearchParser的必然Parser

与往常一样,CoffeeScript主页(http://jashkenas.github.com/coffee-script/)上的“Try CoffeeScript”按钮是您的朋友!

3

首先,你所谈论的概念不是“范围” - 它的this,也非正式地称为“环境”。这当然是JavaScript(也就是CoffeeScript)中最棘手的概念之一,尽管规则相当简单。也许这是因为单词this本身似乎并不像它的意思应该如此轻易地改变,这取决于函数的调用方式......

尼古拉斯的答案是死的,但我建议你也阅读在this上,并试图真正理解它,而不是一直只使用=>(这是一个伟大的工具,但并不总是正确的)。一些资源,我建议: