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

时间:2013-06-12 03:25:26

标签: javascript coffeescript

我是CoffeeScript的新手,我一直都是reading this book。有一个名为选择的部分讨论了使用典型的函数式编程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:攻击未定义

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

我该如何避免这种情况?


实际上,我已经找到了一种方法。这就是修改第一个片段来说明这一点:

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

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

如果你明确告诉它,Coffeescript将使用全局“窗口”。如果我是你,我会犹豫是否开始直接将属性分配给窗口。至少你可以将它们全部放在窗口上的一个对象中,如: 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']。attack和window ['moduleName']。anotherThing。

如果您的应用会变大,您可以查看模块依赖库,例如requirejsbrowserify

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