2

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

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

在我的视图和模型中,随着我的应用程序变大,我开始出现错误,因为与 self 的定义存在冲突。

4

2 回答 2

7

短版:第一版 == 错误。

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

长版:

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

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

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

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

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

那么它是如何工作的呢?好吧,在那个版本中,你这样做:

MyModel = Backbone.Model.extend({

不是:

var MyModel = Backbone.Model.extend({

所以这和这样做是一样的:

window.MyModel = Backbone.Model.extend({

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

我认为最重要的一点是:总是声明(即var)你的 JAVASCRIPT 变量。我不同意克罗克福德所说的一切,但他在这一点上是完全正确的。如果你不养成这个习惯,你会得到很多错误(有 Require 和没有)。

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

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

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

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

于 2012-07-12T20:32:52.327 回答
2
MyModel = Backbone.Model.extend({});

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

实际上它是错误的,它是偶然的。您应该通过其他模块中的参数访问您的模块returndefine

像这样:

return Backbone.Model.extend({});

您应该使用严格模式来避免 JS 中的全局变量出现问题。

此外,JS 中的构造函数只是一个用于运行的函数new。Backboneextend总是返回一个构造函数,你可以通过调用构造函数来创建一个模型实例new,就像你在两个例子中所做的一样。

于 2012-07-12T20:35:27.670 回答