CoffeeScript 范围问题

发布于 2024-11-08 02:24:33 字数 943 浏览 0 评论 0原文

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

What am I doing wrong here? I'm using the fat arrows => for my callbacks, however when the code reaches cb.onEndElement and calls @returner I get an null object exception. So why doesn't @returner exist?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山人契 2024-11-15 02:24:33

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

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

  1. 您应该将 @searchParser = new xml.SaxParser (cb) => ... 在你的构造函数中,而不是考虑到你调用它的方式。
  2. 否则你可以使用 searchParser: () =>; new xml.SaxParser (cb) => 并用下面的括号调用它:@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)

编译的 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 如何将其回调绑定到 this 以及 searchParser 的回调如何绑定到 解析器

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

Your method search needs a fat-arrow => in order to bind it to instances of Parser.

Additionally, although the line searchParser: new xml.SaxParser (cb) => compiles, it's probably not doing what you want, because the fat arrow is binding the callback to Parser and not this. You have two options:

  1. you should probably put @searchParser = new xml.SaxParser (cb) => ... in your constructor instead, given the way you are calling it.
  2. otherwise you could use searchParser: () => new xml.SaxParser (cb) => and call it with parens lower down: @searchParser().parseString str, which would create a searchParser method bound to this

As an example, here are my two solutions, as well as your original line, slightly simplified, as well as the compiled code, for compare and contrast purposes:

Simplified example in 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)

Compiled 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);

Note how searchParser1 and searchParser2 have their callbacks bound to this and searchParser's is bound to Parser.

As always, the "Try CoffeeScript" button at the CoffeeScript homepage (http://jashkenas.github.com/coffee-script/) is your friend!

南风起 2024-11-15 02:24:33

首先,您谈论的概念不是“范围”,而是“this”,也非正式地称为“上下文”。尽管规则相当简单,但它无疑是 JavaScript(以及 CoffeeScript)中最棘手的概念之一。也许是因为 this 这个词本身,它的含义似乎不应该那么容易地根据函数的调用方式而改变......

尼古拉斯的答案是完全正确的,但我建议您还阅读了 this 并尝试真正理解它,而不是一直使用 => (这是一个很棒的工具,但并不总是正确的) 。我推荐的一些资源:

First off, the concept you're talking about isn't "scope"—it's this, also informally called the "context." And it's certainly one of the trickiest concepts in JavaScript (and thus CoffeeScript), even though the rules are fairly simple. Perhaps it's because the word this itself, which doesn't seem like its meaning should be so easily changed depending on how a function is called...

Nicholas' answer is dead-on, but I recommend that you also read up on this and try to really understand it, rather than just using => all the time (it's a great tool, but not always the right one). A few resources I recommend:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文