CoffeeScript范围问题

时间:2011-05-18 01:09:49

标签: javascript coffeescript

我在这里做错了什么?我正在使用胖箭=>对于我的回调,但是当代码到达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

2 个答案:

答案 0 :(得分: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的{​​{1}}方法
  3. 作为一个例子,这里是我的两个解决方案,以及您的原始行,略微简化,以及编译代码,用于比较和对比:

    CoffeeScript中的简化示例:

    this

    编译JavaScript:

    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)
    

    请注意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); searchParser1的回调绑定到searchParser2this的约束searchParser。{/ p>

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

答案 1 :(得分:3)

首先,你所谈论的概念不是“范围” - 即this,也非正式地称为“背景”。它肯定是JavaScript(以及CoffeeScript)中最棘手的概念之一,即使规则相当简单。也许是因为单词this本身看起来不像它的意思应该如此容易改变,这取决于函数的调用方式......

Nicholas的答案是死的,但我建议您也阅读this并尝试真正理解它,而不是一直只使用=>(这是一个很棒的工具,但并不总是正确的)。我建议的一些资源: