【问题标题】:How do I properly scope functions with CoffeeScript in browser?如何在浏览器中使用 CoffeeScript 正确定义函数范围?
【发布时间】:2011-12-08 02:23:46
【问题描述】:
(->
  jQuery ->
    globalThis = @
    $('#emailTypes').change ->
      globalThis.toggleEmailOptions()

  toggleEmailOptions = ->
    $('.emailTypeOptions').fadeOut 'fast', ->
      for emailType in $('#emailTypes').val()
        $("##{emailType}Options").fadeIn()


).call this

这是我的.coffee 文件。但是,toggleEmailOptions 函数不在 jQuery ready 的范围内。我怎样才能使它在范围内?

【问题讨论】:

  • 因为 toggleEmailOptions 无论如何都是一个局部变量,你可以将它移动到 jQuery.Ready 回调中。如果你想让 toggleEmailOptions 在全局范围内可用,你可以使用 => 代替 -> 来保留 this 内部函数并声明 @toggleEmailOptions 代替 toggleEmailOptions

标签: javascript coffeescript scope


【解决方案1】:

来自http://jashkenas.github.com/coffee-script/

适用于 CoffeeScript 的常见注意事项 — 您的内联脚本将 在闭包包装器中运行,所以如果你想公开全局 变量或函数,将它们附加到窗口对象。

如果你使用的是 node.js,或者绑定到exports

对于你的例子,它变成:

window.toggleEmailOptions = ->

【讨论】:

  • ' $('#emailTypes').change -> window.toggleEmailOptions() ' 似乎不起作用 =(
  • 尝试最后不带括号。您绑定的是调用函数的结果值,而不是函数本身。
  • 如果我想做文件范围的怎么办?我不希望它被绑定到窗口......只是在这个特定文件中的“全局”?
  • 不是 100% 确定,但我认为 window == this 用于您的“文件范围”,这是默认设置的。看看webreflection.blogspot.com/2009/10/…
  • @Marius,你是对的 @/this == window 默认在浏览器上下文中的coffeescript中
【解决方案2】:

我认为您不需要包装,因为咖啡脚本已经这样做了,这就是我将如何重写您的代码:

jQuery ->
  toggleEmailOptions = ->
    $('.emailTypeOptions').fadeOut 'fast', ->
      for emailType in $('#emailTypes').val()
        $("##{emailType}Options").fadeIn()

  $('#emailTypes').change ->
    toggleEmailOptions()

【讨论】:

  • 这很好,但这意味着我总是必须在使用函数之前定义它们。我宁愿不这样做,因为我想以一种特定的方式组织我的代码。
  • 实际上你不必先声明它,它只是更容易阅读恕我直言,复制粘贴到js2coffee.org你会看到toggleEmailOptions变量在回调的开头声明了所有案例;)
【解决方案3】:

这里有几个问题。一是您似乎假设 @/this 是来自 jQuery 回调的全局对象 (window)。但很容易看出它不是:

jQuery -> console.log @ is window  # false

请记住,可以在库需要的任何上下文中调用回调。在这种情况下,@document。而且document.toggleEmailOptions 不存在。

此外,如果您希望 toggleEmailOptions 成为全局变量,则需要将其附加到 window(或 @/this,因为 @ is window 在文件的最外层范围内)。那是因为当你只写toggleEmailOptions = ... 时,CoffeeScript 使用var 声明将其范围限定在文件中。通过查看编译后的 JS 很容易看出这一点:vars 始终处于其作用域的顶部。幸运的是,无论如何,文件范围都是您想要的。

所以基本上:不要想太多!你想要的是:

jQuery ->
  $('#emailTypes').change ->
    toggleEmailOptions()

其余部分保持原样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    • 2018-05-18
    • 2019-12-09
    • 1970-01-01
    相关资源
    最近更新 更多