有人能解释一下之间的根本区别吗
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({});
在这里,您不是返回构造函数,而是定义一个全局变量,然后在不同的模块中访问它。
事实上,这是错误的,它是偶然发生的。您应该从define
中return
您的模块,并通过其他模块中的参数访问它们。
像这样:
return Backbone.Model.extend({});
您应该使用严格模式来避免JS中的全局变量出现问题。
此外,JS中的构造函数只是一个要使用new
运行的函数。Backbone extend
总是返回一个构造函数,您可以通过使用new
调用构造函数来创建一个模型实例,就像您在两个示例中所做的那样。