Meteor 中的全局变量

Posted

技术标签:

【中文标题】Meteor 中的全局变量【英文标题】:Global variables in Meteor 【发布时间】:2015-02-15 00:42:25 【问题描述】:

我有

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。很明显,我必须在我的 collections.js 文件中定义 Schemas 而不是将它们分开。但是 Meteor 如何处理单独文件中的代码?我可以访问一些对象和变量,而另一些则无法访问。

【问题讨论】:

Schemas 是全局变量吗?您是否使用require 加载它?也许您需要向我们展示更多代码,因为编写代码时应该没有问题 How can I access constants in the lib/constants.js file in Meteor?的可能重复 【参考方案1】:

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

var someVar = 'someValue';

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

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

someVar = 'someValue';

默认情况下,这将在您的所有应用程序中定义一个变量,尽管您可以通过在specific recognized folder(例如clientserver 文件夹)中编写该声明来限制它。

但是,这个变量不会首先被绝对定义。它将在 Meteor 运行定义它的实际代码时定义。因此,这可能不是最佳实践,因为您将难以处理加载顺序,并且它将使您的代码取决于 Meteor loads files: 您将文件放入哪个文件夹,文件的名称...您的如果你稍微接触一下你的架构,代码很容易出现混乱的错误。

正如我在another closely related post 中建议的,你应该直接去买一个包!

【讨论】:

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

Meteor 中使用 var 关键字声明的变量的作用域仅限于声明它们的文件。

如果你想创建一个全局变量这样做

Schemas = 

【讨论】:

我不确定我对此有何感想...是否没有 ES6/webpack 风格的方法可以从另一个文件导入变量以避免全局变量?【参考方案3】:

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”。 (Node 知道将 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)在节点中工作,但在浏览器中没有全局。所以它没有达到它的目的。

所以我放弃了第一次在 lib 中覆盖它,如果有任何内容被覆盖,则查找运行时错误。

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

这是其他一些JS shorthand tips。

【讨论】:

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

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

【讨论】:

也可以使用 delete Session.keys[sessionName] 删除会话变量。链接:***.com/questions/10743703/…

以上是关于Meteor 中的全局变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Meteor 中为全局变量创建自己的命名空间?

如何判断函数中的变量是全局变量还是局部变量

VC中public定义的变量与全局变量的区别??

C语言中的全局变量和局部变量

php中的全局变量引用

全局变量和局部变量