流星中的全局变量

问题描述 投票:27回答:4

我有

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如何在单独的文件中使用代码?我可以访问一些对象和变量,而其他对象和变量是无法访问的。

javascript node.js meteor scope
4个回答
57
投票

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

var someVar = 'someValue';

在你的.js文件的根目录下,Meteor使用IIFE将其范围限定到文件。

如果要定义全局变量,只需不要编写var,给出:

someVar = 'someValue';

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

但是,这个变量不会首先被绝对定义。它将在Meteor运行定义它的实际代码时定义。因此,它可能不是最好的做法,因为你将很难处理加载顺序,它将使你的代码依赖于Meteor loads files:你把文件放在哪个文件夹,文件的名称...你的代码是如果你稍微触摸你的架构,就容易出现凌乱的错误。

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


11
投票

使用var关键字声明的Meteor中的变量的范围限定在它们声明的文件中。

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

Schemas = {}

3
投票

ReferenceError是一个Node错误。 Meteor是Node之上的框架。

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

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

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

/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 = something || {} something.blah = foo;

这是其他一些JS shorthand tips


1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.