CoffeeScript词法作用域和变量安全

2018-08-25 14:40 更新

变量是使用的时候隐式声明的(没有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

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号