Meteor 中的全局变量

IT技术 javascript node.js meteor scope
2021-02-18 06:29:35

我有

var Schemas = {};

Meteor.isClient && Template.registerHelper("Schemas", Schemas);

Schemas.Person = new SimpleSchema({
  fullName: {
    type: String,
    index: 1,
    optional: true,
  },
  email: {
    type: String,
    optional: true
  },
  address: {
    type: String,
    optional: true
  },
  isActive: {
    type: Boolean,
  },
  age: {
    type: Number,
    optional: true
  }
});

在一个文件中

var Collections = {};

Meteor.isClient && Template.registerHelper("Collections", Collections);

Persons = Collections.Persons = new Mongo.Collection("Persons");
Persons.attachSchema(Schemas.Person);

在另一个文件中。

我收到错误ReferenceError: Schemas is not defined很明显,我必须Schemas在我的collections.js文件中定义而不是将它们分开。但是 Meteor 如何处理单独文件中的代码?我可以访问某些对象和变量,而其他对象和变量则无法访问。

4个回答

当您以经典的 JavaScript 方式定义变量时:

var someVar = 'someValue';

.js文件的根目录 Meteor 使用IIFE将其范围限定为文件

如果你想定义一个全局变量,就不要写var,给出:

someVar = 'someValue';

这将定义默认情况下,所有应用程序中的变量,虽然你可以通过写在该声明限制其特定的认可文件夹clientserver例如文件夹)。

但是,不会绝对首先定义此变量。当 Meteor 运行定义它的实际代码时,它将被定义。因此,这可能不是最佳实践,因为您将在加载顺序上遇到困难,并且它会使您的代码依赖于Meteor 加载文件的方式:您将文件放入哪个文件夹,文件名...您的如果您稍微触及您的架构,代码很容易出现混乱的错误。

正如我在另一篇密切相关的帖子中所建议的,您应该直接购买包裹!

我尝试在 lib 目录中定义我的全局变量,但包肯定更健壮
2021-04-20 06:29:35
我想补充一点,这真的很酷,因为您可以在 /client 中有一个 constants.js 文件,在 /server 目录中有另一个。如果你想在两者之间共享一个常量文件,你可以在 /lib/constants 中创建它。
2021-04-27 06:29:35
这不是 Meteor 的问题。请参阅下面的 ReferenceError。
2021-05-12 06:29:35

Meteor 中用var关键字声明的变量的作用域是它们声明的文件。

如果要创建全局变量,请执行此操作

Schemas = {}
我不确定我对此的感受......是否没有 ES6/webpack 风格的方式从另一个文件导入变量,以便我可以避免全局变量?
2021-04-19 06:29:35

ReferenceError是一个节点错误。Meteor 是一个基于 Node.js 的框架。

Node 有一个全局范围(又名 Node 的global变量)。 如果您尝试访问未定义的全局变量,则 Node(而非 Meteor)会抛出此错误。

浏览器还有一个名为 的全局范围window,并且在访问未定义的变量时不会抛出 ReferenceErrors。

这是我喜欢为类添加功能的模式(它非常 Meteor):

/lib/Helpers.js      <-- Helpers for everyone (node+browser)
/server/Helpers.js   <-- Server helpers (node)
/client/Helpers.js   <-- Client helpers (browser)

考虑这些实现:

// /lib/Helpers.js
Helpers = {/* functions */};  // Assigned to window.Helpers and global.Helpers

// /server/Helpers.js
Helpers = _.extend(Helpers, {/*more functions*/}

// /client/Helpers.js
Helpers = _.extend(Helpers, {/*more functions*/}

这是一个简单的例子。如果我不想担心加载顺序怎么办?为什么不在 /lib/Helpers.js 中使用 _.extend()?

// /lib/Helpers.js
// Helpers = {/* functions */};                  // Overwrites...
Helpers = _.extend(Helpers, {/* functions */});  // ReferenceError

因为如果 Helpers 未定义,您将从 Node 获得 ReferenceError - 特别是用作参数的“Helpers”。(节点知道将 Helpers 分配为 global.Helpers)。

这里有两种方法可以“解决”这个问题:

1)为某事分配助手

// /lib/Helpers.js
// Helpers = Helpers || {}    // would be another ReferenceError
if (typeof Helpers === 'undefined') Helpers = {};
Helpers = _.extend(Helpers, {/* functions */});

2)使用来自全球的助手

// /lib/Helpers.js
Helpers = _.extend(global.Helpers, {/* functions */});  // works in node, but...

这两个都很烂。

1) 的语法很糟糕。
2) 在 node 中工作,但在浏览器中没有全局。所以它失败了它的目的。

所以我放弃并回到第一次在 lib 中覆盖它,并在任何被覆盖的情况下查找运行时错误。

如果你有一个方便的跨浏览器语法,请评论 :-) var something = something || {} something.blah = foo;

这里有一些其他的JS 速记技巧

你能解释一下你为什么提到 ES6 以及这与这个问题有什么关系吗?
2021-04-22 06:29:35
@Fletch 嗯...实际上没有。所以我删除了它。出于某种原因,我认为 ES6 module将有助于清理全局命名空间,但我找不到任何相关信息:-/
2021-04-24 06:29:35
请注意,必须在每个需要使用全局变量的文件的开头添加第三段代码,以便每个变量使用。
2021-05-07 06:29:35

会话变量是全局的,可以很容易地在不同的文件/函数中访问。Session.setPersistent 用于在所有文件中持久设置变量名称。当他们的应用程序太大时,人们可能会限制使用会话变量,因为它们不会被删除(因此可能会出现内存泄漏)并且可能会在控制台中出现错误(如果未定义等)。链接到文档:https : //docs.meteor.com/api/session.html

也可以使用 delete Session.keys[sessionName] 来删除会话变量。链接:stackoverflow.com/questions/10743703/...
2021-04-30 06:29:35