关于 CoffeeScript 变量范围的困惑

Posted

技术标签:

【中文标题】关于 CoffeeScript 变量范围的困惑【英文标题】:Confusion about CoffeeScript variable scope 【发布时间】:2012-04-09 13:47:59 【问题描述】:

我试图了解 CoffeeScript 变量的作用域。 根据文档:

这种行为实际上与 Ruby 的本地作用域相同 变量。

但是,我发现它的工作方式不同。

在 CoffeeScript 中

a = 1
changeValue = -> a = 3
changeValue()
console.log "a: #a" #This displays 3

在红宝石中

a = 1
def f
  a = 3
end
puts a #This displays 1

谁能解释一下?

【问题讨论】:

【参考方案1】:

Ruby 的局部变量(以 [a-z_] 开头)are really local to the block they are declared in。因此,您发布的 Ruby 行为是正常的。

在您的 Coffee 示例中,您有一个 closure 引用 a。这不是函数声明。

在您的 Ruby 示例中,您没有闭包而是函数声明。这是不同的。相当于您的 Coffee 的 Ruby 是:

a = 1
changeValue = lambda do
   a = 3
end
changeValue()

在闭包中,声明块时出现的局部变量在块执行时仍然可以访问。这是闭包的(一种)力量!

【讨论】:

【参考方案2】:

changeValue 函数内部使用的a 变量是全局a 变量。该 CoffeeScript 将被编译成以下 javascript

var a, changeValue;
a = 1;
changeValue = function() 
  return a = 3;
;
changeValue();
console.log("a: " + a);

为了使changeValue 不改变a 变量(即使用局部变量),您需要为名为@9​​87654328@ 的函数提供一个参数(这将创建一个作为局部变量该函数)或使用var a = 3;a 声明为函数内的局部变量(不确定CoffeeScript 会是什么,我不是CoffeeScript 人)。

Some examples of JavaScript variable scope.

【讨论】:

我了解 JavaScript 案例。但是在 CoffeeScript 中,我认为局部变量应该总是隐藏全局变量,因为当我定义一个函数时,我不能考虑所有的全局变量。

以上是关于关于 CoffeeScript 变量范围的困惑的主要内容,如果未能解决你的问题,请参考以下文章

无法重新声明块范围变量(打字稿)

类定义中的变量范围令人困惑

CoffeeScript/Backbone/Marionette - 教程示例转换和范围问题

Ember 的乐趣,CoffeeScript 优先

关于 pthread_exit 释放自动变量的困惑

CoffeeScript 中是不是遗漏了 `do...while` 循环...?