【问题标题】:coffeescript scope of variable assignment vs property assignment in object's other properties变量赋值的咖啡脚本范围与对象其他属性中的属性赋值
【发布时间】:2014-12-08 09:46:11
【问题描述】:

我正在为Ubersicht 编写一些小部件。它使用 node.js 服务器并将每个 .coffee 文件视为独立的小部件对象。我在定义要在一个文件中使用的常量设置时遇到问题。目前我知道有两种方法可以在文件顶部定义这种类型的常量。

# Way 1
foo_1 = true
bar_1 = false
# Way 2
foo_2: true
bar_2: false

在同一个文件中,属性被分配为字符串或函数。上述两种定义选项的方法中的每一种都只适用于两种属性类型中的一种。

staticProperty: """Output #{foo_1} works here
but output of #{foo_2} doesn't work
"""

methodProperty: (input) -> 
  if foo_1 # Raises foo_1 is not defined
  if @foo_1 # foo_1 is undefined which is expected
  if @foo_2 # This works fine

我了解方式 2 添加到对象的属性,但我不太确定 1 分配的方式是如何工作的,因为文件本质上是定义一个对象。你能解释一下吗?

还有没有办法定义一个可以从两个地方访问的变量?

【问题讨论】:

    标签: coffeescript scope


    【解决方案1】:

    我们将看一个丑陋的大例子,看看发生了什么:

    class C
        a: 6
        b: @::a
        c = 11
        d: c
        @e = 23
        f: @e
        g: -> @a
        h: -> C::b
        i: -> c
        j: -> @constructor.e
    

    a 是一个普通的旧属性,在 JavaScript 中它看起来像:

    C.prototype.a = 6;
    

    b 也是一个普通的旧属性,附加在原型上;这里:

    b: @::a
    

    @ 是类本身,所以在 JavaScript 中是:

    C.prototype.b = C.prototype.a
    

    一切正常。

    c 是一种私有变量。在 JavaScript 中它看起来像这样:

    var C = (function() {
      function C() {}
      var c = 11;
      //...
    })();
    

    我在这里包含了更多的 JavaScript 上下文,以便您可以看到 c 的范围。 cC 定义内的任何东西都是可见的,但在其他任何地方都不可见。

    d 是原型上的另一个属性,在 JavaScript 中如下所示:

    C.prototype.d = c
    

    此分配发生在用于构建类的 SIF 包装器内,因此var c = 11 在此处可见。

    e 是一个类属性,在 JavaScript 中只是:

    C.e = 23;
    

    f 是原型上的另一个属性。 @ 是此上下文中的类本身(就像在 b 中一样):

    f: @e
    

    所以我们可以将e 设为@e,JavaScript 看起来像:

    C.prototype.f = C.e;
    

    gh 方法应该很清楚。 i 方法之所以有效,是因为它是 SIF 内部的一个闭包,用于定义 C

    C.prototype.i = function() { return c; };
    

    j 方法之所以有效,是因为它使用标准的constructor property 来返回C 本身。

    演示:http://jsfiddle.net/ambiguous/tg8krgh2/


    将所有这些应用于您的情况,

    class Pancakes
      foo_1 = true
      foo_2: true
    

    我们发现,如果您正确引用事物,您可以使用任何一种方法:

    staticProperty: """Output #{foo_1} works here
    and so does #{@::foo_2}
    """
    
    methodProperty: (input) -> 
      # foo_1 should work fine in here.
      # @foo_1 is undefined which is expected
      # @foo_2 works fine
    

    我不确定您为什么在 methodProperty 中引用 foo_1 时遇到问题,它应该可以正常工作,并且 does work fine 与当前版本的 CoffeeScript 一起使用。

    【讨论】:

    • 这是非常有用的,并且清除了很多东西。 Ubersicht 对对象做了一些事情。首先将.coffee 文件作为文本读入并通过eval。这不应该是一个问题。我认为问题在于该对象被复制到一个新对象,例如new[k] = v for k, v of old,因此它丢失了所有私有变量。这就是 foo_1 未定义的原因。尝试使用@::foo_2 会得到cannot read property 'foo_2' of undefined。这个我还不明白。
    • @::foo_2 错误可能是由某些情况下的复制引起的,如果 Ubersicht 只是使用 for ... of 循环复制属性,那么您将失去原型(AKA @::) .如果将方法视为普通函数,它也可能会丢失@
    猜你喜欢
    • 2016-06-15
    • 1970-01-01
    • 2020-07-12
    • 2011-03-05
    • 2012-07-11
    • 1970-01-01
    • 2015-10-17
    • 2018-06-16
    • 1970-01-01
    相关资源
    最近更新 更多