2011-05-18 198 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上,並試圖真正理解它,而不是一直只使用=>(這是一個偉大的工具,但並不總是正確的)。一些資源,我建議: