主干和RequireJS冲突-实例或构造函数

Backbone and RequireJS conflicts - instances or constructors?

本文关键字:实例 构造函数 冲突 RequireJS      更新时间:2023-09-26

有人能解释一下之间的根本区别吗

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

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

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

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

长版本:

主干模块的工作方式是运行"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)您的Java脚本变量。我不同意克罗克福德说的每一句话,但他在这一点上完全正确。如果你不养成这个习惯,你会遇到很多错误(有Require和没有Require)。

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

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

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

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

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

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

事实上,这是错误的,它是偶然发生的。您应该从definereturn您的模块,并通过其他模块中的参数访问它们。

像这样:

return Backbone.Model.extend({});

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

此外,JS中的构造函数只是一个要使用new运行的函数。Backbone extend总是返回一个构造函数,您可以通过使用new调用构造函数来创建一个模型实例,就像您在两个示例中所做的那样。