11

给定以下代码:

outer=1
f=->
  local=1
  outer=0
  local+outer

coffeescript 创建了一个varfor localbut re-ueses outer

var f, outer;

outer = 1;

f = function() {
  var local;
  local = 1;
  outer = 0;
  return local + outer;
};

这是您的期望。

但是,如果您在函数中使用局部变量,则该变量是否声明为局部变量取决于外部范围。我知道这是一个功能,但它导致了一些错误,因为我必须检查所有外部范围是否有同名的变量(在我的函数之前声明)。我想知道是否有办法通过在本地声明变量来防止这种类型的错误?

4

5 回答 5

12

当您没有使用适当的描述性变量名称时,通常会出现这种错误。也就是说,有一种方法可以隐藏外部变量,尽管接受的答案是这样说的:

outer=1
f=->
  do (outer) ->
    local=1
    outer=0
    local+outer

这创建了一个 IIFE,outer因为它是一个论点。函数参数就像var关键字一样隐藏外部变量,因此这将具有您期望的行为。然而,就像我说的,你真的应该更描述性地命名你的变量。

于 2013-08-14T15:23:52.813 回答
6

不, CoffeeScript中明确提供该功能(强调我的):

这种行为实际上与 Ruby 的局部变量作用域相同。因为您无法直接访问var关键字,所以不可能故意隐藏外部变量,您只能引用它。因此,如果您正在编写一个深度嵌套的函数,请注意不要意外重用外部变量的名称。

于 2013-08-14T11:49:26.887 回答
6

你可以使用反引号将纯 JavaScript 注入到 CoffeeScript 中:

outer=1
f=->
  local=1
  `var outer=0`
  local+outer

在大多数情况下,我会尽量避免这种情况,而是更愿意重命名外部变量,在它们的名称中指明它们的范围/上下文。但是,有时这很有帮助,例如,在使用调试模块时,我总是希望有一个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;    
})();

我喜欢这种直接声明变量的方式,而不是(恕我直言)更慢且可读性更低的 IIFE hack。

于 2014-07-30T09:16:38.597 回答
2

正如 Aaron 指出的那样,阴影确实是可能的:

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
于 2014-02-03T10:04:53.887 回答
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()
于 2014-09-09T13:45:41.843 回答