CoffeeScript范围问题

Mat*_*hew 5 javascript coffeescript

我在这做错了什么?我正在使用fat arrows =>作为我的回调,但是当代码到达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
Run Code Online (Sandbox Code Playgroud)

nic*_*ten 5

您的方法search需要一个胖箭头=>才能将其绑定到实例Parser.

另外,虽然该行searchParser: new xml.SaxParser (cb) =>编译,但它可能没有做你想要的,因为胖箭头绑定回调Parser而不是this.您有两种选择:

  1. @searchParser = new xml.SaxParser (cb) => ...考虑到你调用它的方式,你应该把它放在你的构造函数中.
  2. 否则你可以用searchParser: () => new xml.SaxParser (cb) =>下来的parens来调用它@searchParser().parseString str,这将创建一个searchParser绑定的方法this

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

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)
Run Code Online (Sandbox Code Playgroud)

编译的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);
Run Code Online (Sandbox Code Playgroud)

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

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