关于CoffeeScript变量作用域的困惑

6

我正在尝试理解CoffeeScript的变量作用域。

这种行为与Ruby的本地变量范围完全相同。

然而,我发现它的工作方式不同。

在CoffeeScript中:

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

在Ruby中
a = 1
def f
  a = 3
end
puts a #This displays 1

请问有人能解释一下吗?

(内容涉及IT技术)
2个回答

8
Ruby的局部变量(以[a-z_]开头)真正地局限于它们声明所在的块中。因此,你发布的Ruby行为是正常的。
在你的Coffee示例中,你有一个引用a的闭包。这不是一个函数声明。
在你的Ruby示例中,你没有一个闭包而是一个函数声明。这是不同的。与你的Coffee相对应的Ruby代码是:
a = 1
changeValue = lambda do
   a = 3
end
changeValue()

在闭包中,当块被声明时存在的局部变量在执行块时仍然是可访问的。这是闭包的(之一)强大之处!

0

changeValue 函数中使用的 a 变量是全局的 a 变量。这段 CoffeeScript 代码将被编译成以下 JavaScript 代码:

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

为了使changeValue不改变a变量(即使用局部变量),您需要在函数中要么有一个名为a的参数(这将创建一个作为该函数局部变量的变量a),要么使用var a = 3;在函数内部声明a为局部变量(我不是CoffeeScript专家,不确定其语法)。

一些JavaScript变量作用域示例。


1
我理解 JavaScript 的情况。但在 CoffeeScript 中,我认为局部变量应该始终遮蔽全局变量,因为当我定义一个函数时,我无法考虑所有全局变量。 - Sam Kong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接