>> 初次用 expressjs 写了点小东西,窃以为变量作用域名是node.js(或者应该是javascript) ugly 的一个地方。
用了很长时间的 node.js 了,真没觉得。
>> 基本每一个模块需要占用一个全局变量,
类似
var m = require('./my_module');
你可以在 node 命令行里 require 你自己的代码,然后输入 m. 按 tab 试试看。全局的可以直接按 tab 看到,或者 global. tab 查看得到。这会让你对 exports 有个感性认识。你需要了解的是 node.js 的 module 机制。参考下面的代码, module 的概念与之类似:
(funciton(){ var a = 1; .... return {x:a}; })();
这个叫啥来着,立即执行的匿名函数?闭包?反正就是这个东西了。
你的 module 对外可见的,只是你
exports.fun = xxx 的部分,其余的一律不可见(我认为,这种机制比起 public private 什么的,至少是一样的强大)。全局变量的问题,基本不用担心。
>> 而且由于回调函数里可能需要使用父级函数的局部变量,所以回调函数嵌套几层之后,感觉使用每一个变量要非常谨慎,每一个变量都是一个炸弹。
...
function some_fun(req,res,next){
redis.incr('next_id', function(e,r){
if(e) return next(e);
redis.set('key', object, function(e,r){
if(e) return next(e);
res.send([1,'ok']);
}
}
}
...
类似这样的回调层次和作用域(不同层次都有 e 和 r 存在,这里,因为有 var shadow 机制,你可以很放心地取相同的名字),没什么可担心的。
回调使用外层的变量,这是 javascript 提供的语法机制,但如果回调里很大量地在使用外层变量,那就有可能是 bad smell 了,这很微妙,但不复杂,这种情况一般都可以很简单地重构为传参的形式。
>> 请问大家是如何规避这个问题?依靠命名规范?或者是我用法是不正确?
我认为你可能是还没有“习惯”。
btw. 个人建议慎用 coffee script 既然 plain javascript 能解决所有的问题,那就没有必要引入实质上是同一种语言(coffe script IS javascript)的另外一套语法。有个老外写过一篇,处处不记得了,转载在这里
http://cliclip.com/#clip/7/521 。