在CoffeeScript中,我如何过滤掉全局数组而不意外地声明它?

In CoffeeScript, how can I filter out a global array without accidentally declaring it?

本文关键字:数组 全局 意外 声明 CoffeeScript 何过滤 过滤      更新时间:2023-09-26

我对CoffeeScript很陌生,我一直在读这本书。有一个名为Select的部分讨论如何使用典型的函数式编程filter函数。它说你可以这样做:

attacks = (attack for attack in attacks when attack is "a")

目的是过滤掉所有不等于"a"的元素。只要在同一文件中声明了attacks,就可以正常工作。但是,如果我在另一个文件中声明了attacks,像这样:

attacks = ["a", "b"]
root = exports ? this
root.attacks = attacks

然后第一个代码像这样编译:

function() {
    var attack, attacks, _i, _len;
    ...

你会在for循环中得到一个错误,说

TypeError: attacks is undefined

这种情况正在发生,我猜,因为CoffeeScript在=的左侧看到了它不知道的东西,并决定需要声明它。

我怎样才能避免这种情况?


事实上,我已经想出了一个方法。那就是修改第一个代码片段,让它这样写:

root.attacks = (attack for attack in attacks when attack is "a")

这是一个好的解决方案吗?

Coffeescript将使用全局"window",如果你显式地告诉它。如果我是你,我会犹豫是否开始直接分配属性到窗口。至少你可以把它们放在一个窗口上的对象中,比如:window.globals = window.globals ? {}然后window.globals.attacks = (attack for attack in attacks when attack is "a")。对于更健壮的解决方案,您可以考虑以下内容:

window['moduleName'] = (->
  someOtherVariableToExpose = 'something'
  # All of your code
  attacks: attacks
  anotherThing: someOtherVariableToExpose)()

在javascript中看起来像:

window['moduleName'] = (function() {
  var someOtherVariableToExpose;
  var attacks;
  someOtherVariableToExpose = 'something';
  attacks = 'whatever your code defined it as';
  return {
    attacks: attacks,
    anotherThing: someOtherVariableToExpose
  };
})();

这将在该文件的所有私有代码周围创建一个漂亮的小闭包,并且只暴露window['moduleName']。['moduleName']. anotherthing .

如果你的应用会越来越大,你可以查看模块依赖库,如requires或browserify

编辑以确保立即调用匿名函数,因此返回的对象确实是所有暴露的。

是的,你的解决方案很好。Coffeescript将为你的引用创建一个局部变量,如果你没有从其他地方显式地把它们拉进来,所以你需要这样做。如果您知道此代码位于节点或浏览器中,则可以更明确地说window.attacks或require()包含攻击的文件并以这种方式抓取它。