javascript CoffeeScript 中的方法调用语法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7200464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:16:26  来源:igfitidea点击:

Method Call Syntax in CoffeeScript

javascriptsyntaxbackbone.jscoffeescript

提问by mportiz08

I'm new to CoffeeScript, and I seem to be having trouble with the syntax for calling methods.

我是 CoffeeScript 的新手,我似乎在调用方法的语法方面遇到了问题。

Here's the Card model:

这是卡模型:

class exports.Card extends Backbone.Model
  defaults:
    pip:   '4'
    suit:  '?'
    color: 'b'

  rows: ->
    rows =
      '4': [2, 0, 2]
    rows[@pip]

And the relevant portion of the template:

以及模板的相关部分:

<ul class="col cols-<%= @card.rows()[0] %>">

which is giving me the error Uncaught TypeError: Object #<Object> has no method 'rows'

这给了我错误 Uncaught TypeError: Object #<Object> has no method 'rows'

Specifically, I'm wondering if I'm using incorrect syntax for the rows method of Card or if I'm just misunderstanding something. Thanks in advance!

具体来说,我想知道我是否对 Card 的行方法使用了不正确的语法,或者我是否只是误解了某些东西。提前致谢!

Update:

更新:

For some reason, @card.propertyalways works fine, but @card.any_method()never does. I've gotten around this at the moment by using properties, but I'd love it if someone was able to explain this behavior. Thanks again!

出于某种原因,@card.property总是工作正常,但@card.any_method()从来没有。目前我已经通过使用属性解决了这个问题,但如果有人能够解释这种行为,我会很高兴。再次感谢!

Update 2:

更新 2:

I'm using http://brunchwithcoffee.comif it's a help to anyone, and here's the main.coffeefile to show how the @cardinstance is being created and passed to the view.

如果它对任何人有帮助,我正在使用http://brunchwithcoffee.com,这里的main.coffee文件显示了如何@card创建实例并将其传递给视图。

window.app = {}
app.routers = {}
app.models = {}
app.collections = {}
app.views = {}

Card = require('models/card_model').Card
MainRouter = require('routers/main_router').MainRouter
HomeView = require('views/home_view').HomeView
CardView = require('views/card_view').CardView

# app bootstrapping on document ready
$(document).ready ->
  app.initialize = ->
    app.routers.main = new MainRouter()
    app.views.home = new HomeView()
    app.views.card = new CardView(model: new Card(color: 'r', suit: '?', pip: '7'))
    app.routers.main.navigate 'home', true if Backbone.history.getFragment() is ''
  app.initialize()
  Backbone.history.start()

回答by liammclennan

Your method calling syntax is correct. The relevant rules for CoffeeScript are:

您的方法调用语法是正确的。CoffeeScript 的相关规则是:

  • Parenthesis are optional for method calls invoked with arguments ie

    object.method 1,2 
    

    or

    object.method(1,2)
    
  • Parenthesis are required for method calls invoked with no arguments ie

    object.method()
    
  • 对于使用参数调用的方法调用,括号是可选的,即

    object.method 1,2 
    

    或者

    object.method(1,2)
    
  • 没有参数调用的方法调用需要括号,即

    object.method()
    

To see how this works try running the following code on the 'Try CoffeeScript' editor on the CoffeeScript site:

要查看这是如何工作的,请尝试在 CoffeeScript 站点上的“Try CoffeeScript”编辑器上运行以下代码:

class A
  method: ->
    console.log "A"

(new A()).method();

Since your method call syntax is correct it seems likely that the problem is that the @card variable is not an instance of the exports.Card class.

由于您的方法调用语法是正确的,问题似乎很可能是 @card 变量不是exports.Card 类的实例。

回答by Trevor Burnham

The problem is that pipisn't a property of the Cardinstance; it's a property of Card::defaults, so Backbone then makes it an attributeof the Cardinstance—not a property. You can access the pipattribute with

问题是这pip不是Card实例的属性;它的属性Card::defaults,因此骨干网则使得它的属性的的Card实例,而不是财产。您可以访问该pip属性

card.get 'pip'

or directly as

或直接作为

card.attributes.pip

The reason for this distinction is that, in JavaScript, there's no way to monitor a property for changes, which Backbone needs to do in order to dispatch events. (If you modify pipwith card.set 'pip', then Backbone fires a "change"event, for instance.)

这种区别的原因是,在 JavaScript 中,没有办法监视属性的更改,而 Backbone 需要这样做才能分派事件。(如果修改pipcard.set 'pip',然后骨干触发一个"change"事件,例如。)

So, your code should work fine if you just change the last line of the rowsmethod:

因此,如果您只更改方法的最后一行,您的代码应该可以正常工作rows

rows: ->
  rows =
    '4': [2, 0, 2]
  rows[@get 'pip']

(Note:Getters/setters are supported in someJS environments, which would allow you to map card.pip = ...to card.set 'pip', ...See John Resig's article on it here. Backbone doesn't use this approach because it aims to be compatible with all modern-ish browsers.)

注意:某些JS 环境中支持 Getter/setter ,这将允许您映射card.pip = ...card.set 'pip', ...See John Resig's article here。Backbone 不使用这种方法,因为它旨在与所有现代浏览器兼容。)

回答by mportiz08

Finally figured it out--I forgot that the @cardvariable referenced in the template didn't originate from the main.coffeefile--it was actually being converted into JSON in the CardViewhere:

终于想通了——我忘@card了模板中引用的变量不是来自main.coffee文件——它实际上在CardView这里被转换为 JSON :

cardTemplate = require('templates/card')

class exports.CardView extends Backbone.View
  tagName:   'div'
  className: 'card'

  render: ->
    $(@el).html cardTemplate(card: @model.toJSON())
    @

Now it makes sense why only variables were working and not methods -- @cardwas actually a JSON representation of the model instance.

现在可以理解为什么只有变量在工作而不是方法 -@card实际上是模型实例的 JSON 表示。

Thanks for all the suggestions/clarifications guys--sorry for the dumb mistake :P

感谢所有的建议/澄清家伙 - 对不起愚蠢的错误:P