混淆全局JS变量的未捕获引用错误

时间:2013-03-11 16:36:21

标签: javascript ruby-on-rails backbone.js coffeescript

在我尝试命名我的代码之前,在rails项目中有2个coffeescript文件生成这个:

(function(){
  window.Investments = {};
}).call(this);

然后我的骨干收藏:

(function(){
  Investments.InfrastructureCollection = Backbone.Collection.extend({});
}).call(this);

chrome中的控制台抛出一个Uncaught ReferenceError: Investments is not defined,我在页面加载时设置了我的InfrastructureCollection,但是一切似乎执行得很好并且事情会加载。我甚至可以创建集合的新实例,并在控制台中添加模型,而无需进行任何设置。在控制台中发生了什么以抛出错误?

3 个答案:

答案 0 :(得分:1)

要检查的第一件事是看是否有效:

var Investments = {};
Investments.InfrastructureCollection = Backbone.Collection.extend({});

没有其他所有东西。然后,如果这不起作用,那么看看是否有效:

window.Investments = {};
window.Investments.InfrastructureCollection = Backbone.Collection.extend({});

这些将验证您是否已创建.Investments对象或是否存在某些问题。

然后,最后我认为你没有理由在两个单独的实例中做这一切:

(function(){

}).call(this);

立即执行的函数通常用于为隐私或局部变量创建临时范围,但是您没有这些范围,因此不需要它。其次,为什么.call(this)。同样,这是一个额外的代码量,根本没有以任何方式使用。如果你希望this保持原样,那么首先要摆脱立即执行的功能块。

如果您仍然无法弄清楚这一点,那么请尝试在jsFiddle中创建一个简单的可重现示例,以便我们可以更准确地了解正在发生的事情。

答案 1 :(得分:0)

不确定您在调用这些内容的上下文中(即this在您的调用中指的是什么)但是您可能应该更改为:

(function(context){
  context.Investments = {};
}).call(window);

也不确定为什么不能在访问InfrastructureCollection之前声明投资

Investments = {};
Investments.InfrastructureCollection = Backbone.Collection.extend({});

答案 2 :(得分:0)

只要按照这样的顺序保持自我调用功能的顺序,你就可以了。命名空间的声明显然必须先于Collection, Model, etc.

/**Initialize namespace */
(function(){
    window.Investments = {};
}).call(this);

/** Collection */
(function(){
    Investments.Collection = Backbone.Collection.extend({});
}).call(this);

/** Model */
(function(){
    Investments.Model = Backbone.Model.extend({});
}).call(this);

OR 只是按原样调用匿名函数并注入Investments对象以确保它确实在范围内(如果特定对象存在,则必须进行额外检查)。 / p>

/**Initialize namespace */
(function(){
    window.Investments = {};
})();

/** Collection */
(function(inv){
    inv.Collection = Backbone.Collection.extend({});
})(window.Investments || {});

/** Model */
(function(inv){
    inv.Model = Backbone.Model.extend({});
})(window.Investments || {});

如果您担心order或模块,可以采取的另一个选择是使用AMD这样的Require JS框架,这样您就不用担心了你可以配置依赖项,它就会运行。