给出以下代码:
outer=1
f=->
local=1
outer=0
local+outer
coffeescript为var
创建local
但重新outer
:
var f, outer;
outer = 1;
f = function() {
var local;
local = 1;
outer = 0;
return local + outer;
};
这是您的期望。
但是,如果在函数中使用局部变量,则如果变量声明为local,则它取决于外部作用域。我知道这是一个功能,但它导致了一些错误,因为我必须检查所有外部作用域的同名变量(在我的函数之前声明)。我想知道是否有办法通过声明变量本地来防止这种类型的错误?
答案 0 :(得分:12)
当您没有使用适当的描述性变量名称时,通常会出现此类错误。也就是说,尽管接受的答案是:
,但有一种方法可以遮蔽外部变量outer=1
f=->
do (outer) ->
local=1
outer=0
local+outer
这会创建一个IIFE,outer
作为一个参数。函数参数与var
关键字一样影响外部变量,因此这将具有您期望的行为。但是,就像我说的那样,你应该更具描述性地命名你的变量。
答案 1 :(得分:6)
不,该功能在CoffeeScript中明确不(强调我的):
这种行为实际上与Ruby的局部变量范围相同。由于您无法直接访问
var
关键字,无法故意隐藏外部变量,因此您只能引用它。因此,如果您正在编写一个深层嵌套的函数,请注意不要意外地重用外部变量的名称。
答案 2 :(得分:6)
您可以使用反引号将纯JavaScript注入到CoffeeScript中:
outer=1
f=->
local=1
`var outer=0`
local+outer
对于大多数情况,我试图避免这种情况,而是宁愿重命名外部变量,在其名称中指出它们的范围/上下文。但是,有时这很有用,例如,在使用 debug 模块时,我总是希望有一个debug()
函数可用于记录,如下例所示:
#logging fn for module setup and other global stuff
debug = require("debug")("foo")
class Bar
#local logging fn to allow Bar instances to log stuff
`var debug = require("debug")("foo:bar")`
如果你想保持简单JS至少只声明变量然后分配使用CoffeeScript:
`var debug`; debug = require("debug") "foo:bar"
示例编译为:
// Generated by CoffeeScript 1.7.1 -- removed empty lines for SO answer
var Bar, debug;
debug = require("debug")("foo");
Bar = (function() {
function Bar() {}
var debug;
debug = require("debug")("foo:bar");
return Bar;
})();
我喜欢这种直接的方式来声明变量比(IMHO)更慢和更不易读的IIFE黑客更好。
答案 3 :(得分:2)
正如亚伦指出的那样,阴影确实是可能的:
outer=1
f=->
do (outer) ->
local=1
outer=0
local+outer
由于局部函数内部不需要外部值,因此可以使用null
进行初始化,以防在某些时候从外部作用域中删除变量outer
(这会导致误差)。
#outer=1
f=->
do (outer=null) ->
local=1
outer=0
local+outer
答案 4 :(得分:0)
important = 10 # global
main = ->
agentId = '007'
console.log 'global `important`', important # refers to the global variable
((important) -> # place the local variables as the arguments
important = 20
console.log 'local `important`', important # locally scoped
console.log 'parent scope value', agentId # even access variables from the above scopes
)() # not passing anything, so the local varibales would be left undefined at first
console.log 'global `important`', important # the global variable remains untouched
main()