Backbone和RequireJS冲突 - 实例或构造函数?

时间:2012-07-12 20:27:33

标签: javascript backbone.js requirejs

有人可以解释之间的根本区别:

define(['backbone'], function(Backbone) {
   MyModel = Backbone.Model.extend({
   });
});

define(['backbone', 'models/mymodel'], function(Backbone){
    var app = Backbone.View.extend({
        initialize: function() {
           var model = new MyModel();
        }
    });
});

define(['backbone'], function(Backbone) {
   var MyModel = Backbone.Model.extend({
   });
   return MyModel;
});

define(['backbone', 'models/mymodel'], function(Backbone, MyModel){
    var app = Backbone.View.extend({
        initialize: function() {
           var model = new MyModel();
        }
    });
});

在前者中,第一个模块只是定义了MyModel。在后者中,它被创建为变量并返回,第二个模块需要在导入时将其放入参数中。

我看到的RequireJS示例似乎在两者之间有所不同,但我真的不明白其中的区别 - 一个返回一个实例而另一个是构造函数吗?

在我的应用程序中,我甚至没有注意到我实际上是在不同的地方使用这两种方式,而且我认为这会导致问题。我使用了很多

self = this
self.model.doSomething

在我的观点和模型中,随着我的应用程序变大,我开始收到错误,因为与自我定义存在冲突。

2 个答案:

答案 0 :(得分:7)

简短版本:第一版==错误。

中等版本:第一个绕过需要完全使用全局变量,而第二个实际使用需要。

长版:

Backbone模块的工作方式是运行“define”,传递一个函数(通常还有一个依赖项数组),从该函数返回的任何内容都定义为该模块。所以,如果我这样做:

// Inside foo.js
define([], function() {
   return 1;
});

我已将“foo”模块定义为1,所以如果我在其他地方执行:

define(['foo'], function(foo) {
    alert(foo); // alerts 1
});

您的第一个版本没有返回任何内容,因此根本不会创建一个Require模块。

那怎么办?好吧,在那个版本中你做了:

MyModel = Backbone.Model.extend({

NOT:

var MyModel = Backbone.Model.extend({

这与做的完全相同:

window.MyModel = Backbone.Model.extend({

然后,当代码的第二部分运行时,它会访问window.MyModel,然后工作......但它完全绕过了过程中的Require.js。

我认为最重要的事情是:总是声明(即var)你的JAVASCRIPT VARIABLES。我不同意克罗克福德所说的一切,但他在这个问题上已经死了。如果你不养成这种习惯,你会得到很多错误(有需要和没有)。

除此之外,下一个最重要的事情可能是:总是从你通过define的功能中回归。在某些特殊情况下,您不想返回任何内容,但除非您故意尝试解决其中一种情况,否则应始终返回一些内容来定义模块。

最后,如果您使用的是Require,则代码中的每个变量都应该:

  • 来自define函数(即它应该是您传递给define的函数的参数变量),或者
  • 应该在该文件中声明(即var - ed)

如果您使用JSLint或'use strict';(如Valentin Nemcev所建议的那样),或者您使用像Eclipse这样的编辑器,您的工具可以帮助您确保这一点(事实上可以很容易地确保)。

答案 1 :(得分:2)

MyModel = Backbone.Model.extend({});

这里你没有返回一个构造函数,你正在定义一个全局变量,稍后在不同的模块中访问它。

实际上这是错误的,它是偶然的。您应return define来自return Backbone.Model.extend({}); 的模块,并通过其他模块中的参数访问它们。

像这样:

new

您应该use strict模式以避免JS中的全局变量出现问题。

此外,JS中的构造函数只是一个与extend一起运行的函数。 Backbone new总是返回一个构造函数,你通过使用{{1}}调用构造函数来创建一个模型实例,就像你在两个例子中一样。