codecamp

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

CoffeeScript对象
CoffeeScript的循环和推导式
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }