我在这里做错了什么?我使用粗箭头=>进行回调,但是当代码到达cb.onEndElement并调用@returner时,我得到一个空对象异常。那么,为什么@returner不存在?

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

最佳答案

您的方法search需要一个粗箭头=>才能将其绑定(bind)到Parser的实例。

此外,尽管searchParser: new xml.SaxParser (cb) =>行可以编译,但它可能并没有执行您想要的操作,因为粗箭头将回调绑定(bind)到Parser而不是this。您有两种选择:

  • ,考虑到调用它的方式,您可能应该将@searchParser = new xml.SaxParser (cb) => ...放到构造函数中。
  • ,否则您可以使用searchParser: () => new xml.SaxParser (cb) =>并以较低的parens调用它:@searchParser().parseString str,这将创建绑定(bind)到searchParserthis方法

  • 例如,这是我的两个解决方案,以及稍作简化的原始行以及编译后的代码,用于比较和对比:

    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的回调如何绑定(bind)到this,而searchParser的回调如何绑定(bind)到Parser

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

    关于javascript - CoffeeScript范围问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6038845/

    10-12 13:20