CoffeeScript词法作用域和变量安全
变量是使用的时候隐式声明的(没有var关键字)
编译器确保变量在词法作用域中声明;已经在作用域中声明的外部变量不会在函数内部再次声明
使用内部变量不会遮蔽外部变量,而只会引用外部变量;因此,不要在深度嵌套的函数中重用外部变量名
CoffeeScript的输入被包装在一个匿名函数中,因此污染全局命名空间的可能性极小
如果要给其他脚本创建顶级变量,要把这些变量作为window对象的属性来声明,或者在CommonJS中作为exports对象的属性来声明:exports ? this
CoffeeScript 编译器会考虑所有变量, 保证每个变量都在词法域里适当地被定义 — 你永远不需要自己去写 var.
outer = 1
changeNumbers = ->
inner = -1
outer = 10
inner = changeNumbers()
var changeNumbers, inner, outer;
outer = 1;
changeNumbers = function() {
var inner;
inner = -1;
return outer = 10;
};
inner = changeNumbers();
注意所有变量的定义都被推到相关的顶层作用域, 也就是第一次出现的位置. outer 在内层的函数里没有被重新定义, 因为它已经存在于作用域当中了. 同时, 内层函数里的 inner 不应该改变外部的同名的变量, 所以在这里有自己的声明.
其行为和 Ruby 的局部变量的作用域实际上是一致的. 由于你没有对 var 关键字的直接访问, 根据需要隐藏一个外部变量就很容易, 你只能引用它. 所以在写深层的嵌套的函数时, 注意不要意外用到和外部变量相同的名字.
尽管要说清楚会受到文档长度限制, 函数的所有 CoffeeScript 结果都被一个匿名函数包裹:(function(){ ... })(); 这层安全的封装, 加上自动生成的 var 关键字, 使得不小心污染全局命名空间很难发生.
如果你希望创建一个其他脚本也能使用的顶层变量, 那么将其作为赋值在 window 上, 或者在 CommonJS 里的 exports 上. 存在操作符(existential operator)可以帮你写出一个可靠的方式找到添加位置; 比如你的目标是同时满足 CommonJS 和浏览器: exports ? this
更多建议: